diff --git a/Core/Code/IO/mitkIOUtil.cpp b/Core/Code/IO/mitkIOUtil.cpp index bf01ca9c70..afe76ce82f 100644 --- a/Core/Code/IO/mitkIOUtil.cpp +++ b/Core/Code/IO/mitkIOUtil.cpp @@ -1,768 +1,774 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ - #include "mitkIOUtil.h" #include "mitkDataNodeFactory.h" #include "mitkImageWriter.h" #include "mitkPointSetWriter.h" #include "mitkSurfaceVtkWriter.h" #include #include #include #include #include #include #include //ITK #include //VTK #include #include #include #include #include static std::string GetLastErrorStr() { #ifdef US_PLATFORM_POSIX return std::string(strerror(errno)); #else // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); std::string errMsg((LPCTSTR)lpMsgBuf); LocalFree(lpMsgBuf); return errMsg; #endif } #ifdef US_PLATFORM_WINDOWS #include #include // make the posix flags point to the obsolte bsd types on windows #define S_IRUSR S_IREAD #define S_IWUSR S_IWRITE #else #include #include #include #endif #include #include static const char validLetters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // A cross-platform version of the mkstemps function static int mkstemps_compat(char* tmpl, int suffixlen) { static unsigned long long value = 0; int savedErrno = errno; // Lower bound on the number of temporary files to attempt to generate. #define ATTEMPTS_MIN (62 * 62 * 62) /* The number of times to attempt to generate a temporary file. To - conform to POSIX, this must be no smaller than TMP_MAX. */ + conform to POSIX, this must be no smaller than TMP_MAX. */ #if ATTEMPTS_MIN < TMP_MAX const unsigned int attempts = TMP_MAX; #else const unsigned int attempts = ATTEMPTS_MIN; #endif const int len = strlen(tmpl); if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) { errno = EINVAL; return -1; } /* This is where the Xs start. */ char* XXXXXX = &tmpl[len - 6 - suffixlen]; /* Get some more or less random data. */ #ifdef US_PLATFORM_WINDOWS { SYSTEMTIME stNow; FILETIME ftNow; // get system time GetSystemTime(&stNow); stNow.wMilliseconds = 500; if (!SystemTimeToFileTime(&stNow, &ftNow)) { errno = -1; return -1; } unsigned long long randomTimeBits = ((static_cast(ftNow.dwHighDateTime) << 32) - | static_cast(ftNow.dwLowDateTime)); + | static_cast(ftNow.dwLowDateTime)); value = randomTimeBits ^ static_cast(GetCurrentThreadId()); } #else { struct timeval tv; gettimeofday(&tv, NULL); unsigned long long randomTimeBits = ((static_cast(tv.tv_usec) << 32) - | static_cast(tv.tv_sec)); + | static_cast(tv.tv_sec)); value = randomTimeBits ^ static_cast(getpid()); } #endif for (unsigned int count = 0; count < attempts; value += 7777, ++count) { unsigned long long v = value; /* Fill in the random bits. */ XXXXXX[0] = validLetters[v % 62]; v /= 62; XXXXXX[1] = validLetters[v % 62]; v /= 62; XXXXXX[2] = validLetters[v % 62]; v /= 62; XXXXXX[3] = validLetters[v % 62]; v /= 62; XXXXXX[4] = validLetters[v % 62]; v /= 62; XXXXXX[5] = validLetters[v % 62]; int fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (fd >= 0) { errno = savedErrno; return fd; } else if (errno != EEXIST) { return -1; } } /* We got out of the loop because we ran out of combinations to try. */ errno = EEXIST; return -1; } // A cross-platform version of the POSIX mkdtemp function static char* mkdtemps_compat(char* tmpl, int suffixlen) { static unsigned long long value = 0; int savedErrno = errno; // Lower bound on the number of temporary dirs to attempt to generate. #define ATTEMPTS_MIN (62 * 62 * 62) /* The number of times to attempt to generate a temporary dir. To - conform to POSIX, this must be no smaller than TMP_MAX. */ + conform to POSIX, this must be no smaller than TMP_MAX. */ #if ATTEMPTS_MIN < TMP_MAX const unsigned int attempts = TMP_MAX; #else const unsigned int attempts = ATTEMPTS_MIN; #endif const int len = strlen(tmpl); if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) { errno = EINVAL; return NULL; } /* This is where the Xs start. */ char* XXXXXX = &tmpl[len - 6 - suffixlen]; /* Get some more or less random data. */ #ifdef US_PLATFORM_WINDOWS { SYSTEMTIME stNow; FILETIME ftNow; // get system time GetSystemTime(&stNow); stNow.wMilliseconds = 500; if (!SystemTimeToFileTime(&stNow, &ftNow)) { errno = -1; return NULL; } unsigned long long randomTimeBits = ((static_cast(ftNow.dwHighDateTime) << 32) - | static_cast(ftNow.dwLowDateTime)); + | static_cast(ftNow.dwLowDateTime)); value = randomTimeBits ^ static_cast(GetCurrentThreadId()); } #else { struct timeval tv; gettimeofday(&tv, NULL); unsigned long long randomTimeBits = ((static_cast(tv.tv_usec) << 32) - | static_cast(tv.tv_sec)); + | static_cast(tv.tv_sec)); value = randomTimeBits ^ static_cast(getpid()); } #endif unsigned int count = 0; for (; count < attempts; value += 7777, ++count) { unsigned long long v = value; /* Fill in the random bits. */ XXXXXX[0] = validLetters[v % 62]; v /= 62; XXXXXX[1] = validLetters[v % 62]; v /= 62; XXXXXX[2] = validLetters[v % 62]; v /= 62; XXXXXX[3] = validLetters[v % 62]; v /= 62; XXXXXX[4] = validLetters[v % 62]; v /= 62; XXXXXX[5] = validLetters[v % 62]; #ifdef US_PLATFORM_WINDOWS int fd = _mkdir (tmpl); //, _S_IREAD | _S_IWRITE | _S_IEXEC); #else int fd = mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); #endif if (fd >= 0) { errno = savedErrno; return tmpl; } else if (errno != EEXIST) { return NULL; } } /* We got out of the loop because we ran out of combinations to try. */ errno = EEXIST; return NULL; } //#endif namespace mitk { - -const std::string IOUtil::DEFAULTIMAGEEXTENSION = ".nrrd"; -const std::string IOUtil::DEFAULTSURFACEEXTENSION = ".stl"; -const std::string IOUtil::DEFAULTPOINTSETEXTENSION = ".mps"; + const std::string IOUtil::DEFAULTIMAGEEXTENSION = ".nrrd"; + const std::string IOUtil::DEFAULTSURFACEEXTENSION = ".stl"; + const std::string IOUtil::DEFAULTPOINTSETEXTENSION = ".mps"; #ifdef US_PLATFORM_WINDOWS -std::string IOUtil::GetProgramPath() -{ - char path[512]; - std::size_t index = std::string(path, GetModuleFileName(NULL, path, 512)).find_last_of('\\'); - return std::string(path, index); -} + std::string IOUtil::GetProgramPath() + { + char path[512]; + std::size_t index = std::string(path, GetModuleFileName(NULL, path, 512)).find_last_of('\\'); + return std::string(path, index); + } #elif defined(US_PLATFORM_APPLE) #include -std::string IOUtil::GetProgramPath() -{ - char path[512]; - uint32_t size = sizeof(path); - if (_NSGetExecutablePath(path, &size) == 0) + std::string IOUtil::GetProgramPath() { - std::size_t index = std::string(path).find_last_of('/'); - std::string strPath = std::string(path, index); - //const char* execPath = strPath.c_str(); - //mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch(execPath,false); - return strPath; + char path[512]; + uint32_t size = sizeof(path); + if (_NSGetExecutablePath(path, &size) == 0) + { + std::size_t index = std::string(path).find_last_of('/'); + std::string strPath = std::string(path, index); + //const char* execPath = strPath.c_str(); + //mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch(execPath,false); + return strPath; + } + return std::string(); } - return std::string(); -} #else #include #include #include -std::string IOUtil::GetProgramPath() -{ - std::stringstream ss; - ss << "/proc/" << getpid() << "/exe"; - char proc[512] = {0}; - ssize_t ch = readlink(ss.str().c_str(), proc, 512); - if (ch == -1) return std::string(); - std::size_t index = std::string(proc).find_last_of('/'); - return std::string(proc, index); -} + std::string IOUtil::GetProgramPath() + { + std::stringstream ss; + ss << "/proc/" << getpid() << "/exe"; + char proc[512] = {0}; + ssize_t ch = readlink(ss.str().c_str(), proc, 512); + if (ch == -1) return std::string(); + std::size_t index = std::string(proc).find_last_of('/'); + return std::string(proc, index); + } #endif -std::string IOUtil::GetTempPath() -{ - static std::string result; - if (result.empty()) + std::string IOUtil::GetTempPath() { -#ifdef US_PLATFORM_WINDOWS - char tempPathTestBuffer[1]; - DWORD bufferLength = ::GetTempPath(1, tempPathTestBuffer); - if (bufferLength == 0) + static std::string result; + if (result.empty()) { - mitkThrow() << GetLastErrorStr(); - } - std::vector tempPath(bufferLength); - bufferLength = ::GetTempPath(bufferLength, &tempPath[0]); - if (bufferLength == 0) - { - mitkThrow() << GetLastErrorStr(); - } - result.assign(tempPath.begin(), tempPath.begin() + static_cast(bufferLength)); +#ifdef US_PLATFORM_WINDOWS + char tempPathTestBuffer[1]; + DWORD bufferLength = ::GetTempPath(1, tempPathTestBuffer); + if (bufferLength == 0) + { + mitkThrow() << GetLastErrorStr(); + } + std::vector tempPath(bufferLength); + bufferLength = ::GetTempPath(bufferLength, &tempPath[0]); + if (bufferLength == 0) + { + mitkThrow() << GetLastErrorStr(); + } + result.assign(tempPath.begin(), tempPath.begin() + static_cast(bufferLength)); #else - result = "/tmp/"; + result = "/tmp/"; #endif - } - - return result; -} - -std::string IOUtil::CreateTemporaryFile(const std::string& templateName, std::string path) -{ - ofstream tmpOutputStream; - std::string returnValue = CreateTemporaryFile(tmpOutputStream,templateName,path); - tmpOutputStream.close(); - return returnValue; -} - -std::string IOUtil::CreateTemporaryFile(std::ofstream& f, const std::string& templateName, std::string path) -{ - return CreateTemporaryFile(f, std::ios_base::out | std::ios_base::trunc, templateName, path); -} + } -std::string IOUtil::CreateTemporaryFile(std::ofstream& f, std::ios_base::openmode mode, const std::string& templateName, std::string path) -{ - if (path.empty()) - { - path = GetTempPath(); + return result; } - path += "/" + templateName; - std::vector dst_path(path.begin(), path.end()); - dst_path.push_back('\0'); - - std::size_t lastX = path.find_last_of('X'); - std::size_t firstX = path.find_last_not_of('X', lastX); - int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; - while (lastX != std::string::npos && (lastX - firstNonX) < 6) + std::string IOUtil::CreateTemporaryFile(const std::string& templateName, std::string path) { - lastX = path.find_last_of('X', firstX); - firstX = path.find_last_not_of('X', lastX); - firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; + ofstream tmpOutputStream; + std::string returnValue = CreateTemporaryFile(tmpOutputStream,templateName,path); + tmpOutputStream.close(); + return returnValue; } - std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1; - int fd = mkstemps_compat(&dst_path[0], suffixlen); - if(fd != -1) + std::string IOUtil::GetDirectorySeparator() { - path.assign(dst_path.begin(), dst_path.end() - 1); - f.open(path.c_str(), mode | std::ios_base::out | std::ios_base::trunc); - close(fd); +#ifdef US_PLATFORM_WINDOWS + return "\\"; +#else + return "/"; +#endif } - else + + std::string IOUtil::CreateTemporaryFile(std::ofstream& f, const std::string& templateName, std::string path) { - mitkThrow() << "Creating temporary file " << &dst_path[0] << " failed: " << GetLastErrorStr(); + return CreateTemporaryFile(f, std::ios_base::out | std::ios_base::trunc, templateName, path); } - return path; -} -std::string IOUtil::CreateTemporaryDirectory(const std::string& templateName, std::string path) -{ - if (path.empty()) + std::string IOUtil::CreateTemporaryFile(std::ofstream& f, std::ios_base::openmode mode, const std::string& templateName, std::string path) { - path = GetTempPath(); - } + if (path.empty()) + { + path = GetTempPath(); + } - path += "/" + templateName; - std::vector dst_path(path.begin(), path.end()); - dst_path.push_back('\0'); + path += GetDirectorySeparator() + templateName; + std::vector dst_path(path.begin(), path.end()); + dst_path.push_back('\0'); - std::size_t lastX = path.find_last_of('X'); - std::size_t firstX = path.find_last_not_of('X', lastX); - int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; - while (lastX != std::string::npos && (lastX - firstNonX) < 6) - { - lastX = path.find_last_of('X', firstX); - firstX = path.find_last_not_of('X', lastX); - firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; + std::size_t lastX = path.find_last_of('X'); + std::size_t firstX = path.find_last_not_of('X', lastX); + int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; + while (lastX != std::string::npos && (lastX - firstNonX) < 6) + { + lastX = path.find_last_of('X', firstX); + firstX = path.find_last_not_of('X', lastX); + firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; + } + std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1; + + int fd = mkstemps_compat(&dst_path[0], suffixlen); + if(fd != -1) + { + path.assign(dst_path.begin(), dst_path.end() - 1); + f.open(path.c_str(), mode | std::ios_base::out | std::ios_base::trunc); + close(fd); + } + else + { + mitkThrow() << "Creating temporary file " << &dst_path[0] << " failed: " << GetLastErrorStr(); + } + return path; } - std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1; - if(mkdtemps_compat(&dst_path[0], suffixlen) == NULL) + std::string IOUtil::CreateTemporaryDirectory(const std::string& templateName, std::string path) { - mitkThrow() << "Creating temporary directory " << &dst_path[0] << " failed: " << GetLastErrorStr(); - } + if (path.empty()) + { + path = GetTempPath(); + } - path.assign(dst_path.begin(), dst_path.end() - 1); - return path; -} + path += GetDirectorySeparator() + templateName; + std::vector dst_path(path.begin(), path.end()); + dst_path.push_back('\0'); -int IOUtil::LoadFiles(const std::vector &fileNames, DataStorage &ds) -{ + std::size_t lastX = path.find_last_of('X'); + std::size_t firstX = path.find_last_not_of('X', lastX); + int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; + while (lastX != std::string::npos && (lastX - firstNonX) < 6) + { + lastX = path.find_last_of('X', firstX); + firstX = path.find_last_not_of('X', lastX); + firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; + } + std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1; + + if(mkdtemps_compat(&dst_path[0], suffixlen) == NULL) + { + mitkThrow() << "Creating temporary directory " << &dst_path[0] << " failed: " << GetLastErrorStr(); + } + + path.assign(dst_path.begin(), dst_path.end() - 1); + return path; + } + + int IOUtil::LoadFiles(const std::vector &fileNames, DataStorage &ds) + { // Get the set of registered mitk::IDataNodeReader services us::ModuleContext* context = us::GetModuleContext(); const std::vector > refs = context->GetServiceReferences(); std::vector services; services.reserve(refs.size()); for (std::vector >::const_iterator i = refs.begin(); - i != refs.end(); ++i) + i != refs.end(); ++i) { - IDataNodeReader* s = context->GetService(*i); - if (s != 0) - { - services.push_back(s); - } + IDataNodeReader* s = context->GetService(*i); + if (s != 0) + { + services.push_back(s); + } } mitk::ProgressBar::GetInstance()->AddStepsToDo(2*fileNames.size()); // Iterate over all file names and use the IDataNodeReader services // to load them. int nodesRead = 0; for (std::vector::const_iterator i = fileNames.begin(); - i != fileNames.end(); ++i) + i != fileNames.end(); ++i) { - for (std::vector::const_iterator readerIt = services.begin(); - readerIt != services.end(); ++readerIt) + for (std::vector::const_iterator readerIt = services.begin(); + readerIt != services.end(); ++readerIt) + { + try + { + int n = (*readerIt)->Read(*i, ds); + nodesRead += n; + if (n > 0) break; + } + catch (const std::exception& e) { - try - { - int n = (*readerIt)->Read(*i, ds); - nodesRead += n; - if (n > 0) break; - } - catch (const std::exception& e) - { - MITK_WARN << e.what(); - } + MITK_WARN << e.what(); } - mitk::ProgressBar::GetInstance()->Progress(2); + } + mitk::ProgressBar::GetInstance()->Progress(2); } for (std::vector >::const_iterator i = refs.begin(); - i != refs.end(); ++i) + i != refs.end(); ++i) { - context->UngetService(*i); + context->UngetService(*i); } return nodesRead; -} + } -DataStorage::Pointer IOUtil::LoadFiles(const std::vector& fileNames) -{ + DataStorage::Pointer IOUtil::LoadFiles(const std::vector& fileNames) + { mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); LoadFiles(fileNames, *ds); return ds.GetPointer(); -} + } -BaseData::Pointer IOUtil::LoadBaseData(const std::string& path) -{ - return LoadDataNode(path)->GetData(); -} + BaseData::Pointer IOUtil::LoadBaseData(const std::string& path) + { + return LoadDataNode(path)->GetData(); + } -DataNode::Pointer IOUtil::LoadDataNode(const std::string& path) -{ + DataNode::Pointer IOUtil::LoadDataNode(const std::string& path) + { mitk::DataNodeFactory::Pointer reader = mitk::DataNodeFactory::New(); try { - reader->SetFileName( path ); - reader->Update(); + reader->SetFileName( path ); + reader->Update(); - if((reader->GetNumberOfOutputs()<1)) - { - MITK_ERROR << "Could not find data '" << path << "'"; - mitkThrow() << "An exception occured during loading the file " << path << ". Exception says could not find data."; - } + if((reader->GetNumberOfOutputs()<1)) + { + MITK_ERROR << "Could not find data '" << path << "'"; + mitkThrow() << "An exception occured during loading the file " << path << ". Exception says could not find data."; + } - mitk::DataNode::Pointer node = reader->GetOutput(); + mitk::DataNode::Pointer node = reader->GetOutput(); - if(node.IsNull()) - { - MITK_ERROR << "Could not find path: '" << path << "'" << " datanode is NULL" ; - mitkThrow() << "An exception occured during loading the file " << path << ". Exception says datanode is NULL."; - } + if(node.IsNull()) + { + MITK_ERROR << "Could not find path: '" << path << "'" << " datanode is NULL" ; + mitkThrow() << "An exception occured during loading the file " << path << ". Exception says datanode is NULL."; + } - return reader->GetOutput( 0 ); - } + return reader->GetOutput( 0 ); + } catch ( itk::ExceptionObject & e ) { - MITK_ERROR << "Exception occured during load data of '" << path << "': Exception: " << e.what(); - mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: " << e.what(); + MITK_ERROR << "Exception occured during load data of '" << path << "': Exception: " << e.what(); + mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: " << e.what(); } -} + } -Image::Pointer IOUtil::LoadImage(const std::string& path) -{ + Image::Pointer IOUtil::LoadImage(const std::string& path) + { mitk::DataNode::Pointer node = LoadDataNode(path); mitk::Image::Pointer image = dynamic_cast(node->GetData()); if(image.IsNull()) { - MITK_ERROR << "Image is NULL '" << path << "'"; - mitkThrow() << "An exception occured during loading the image " << path << ". Exception says: Image is NULL."; + MITK_ERROR << "Image is NULL '" << path << "'"; + mitkThrow() << "An exception occured during loading the image " << path << ". Exception says: Image is NULL."; } return image; -} + } -Surface::Pointer IOUtil::LoadSurface(const std::string& path) -{ + Surface::Pointer IOUtil::LoadSurface(const std::string& path) + { mitk::DataNode::Pointer node = LoadDataNode(path); mitk::Surface::Pointer surface = dynamic_cast(node->GetData()); if(surface.IsNull()) { - MITK_ERROR << "Surface is NULL '" << path << "'"; - mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: Surface is NULL."; + MITK_ERROR << "Surface is NULL '" << path << "'"; + mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: Surface is NULL."; } return surface; -} + } -PointSet::Pointer IOUtil::LoadPointSet(const std::string& path) -{ + PointSet::Pointer IOUtil::LoadPointSet(const std::string& path) + { mitk::DataNode::Pointer node = LoadDataNode(path); mitk::PointSet::Pointer pointset = dynamic_cast(node->GetData()); if(pointset.IsNull()) { - MITK_ERROR << "PointSet is NULL '" << path << "'"; - mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: Pointset is NULL."; + MITK_ERROR << "PointSet is NULL '" << path << "'"; + mitkThrow() << "An exception occured during loading the file " << path << ". Exception says: Pointset is NULL."; } return pointset; -} + } -bool IOUtil::SaveImage(mitk::Image::Pointer image, const std::string& path) -{ + bool IOUtil::SaveImage(mitk::Image::Pointer image, const std::string& path) + { std::string dir = itksys::SystemTools::GetFilenamePath( path ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutExtension( path ); std::string extension = itksys::SystemTools::GetFilenameExtension( path ); if (dir == "") dir = "."; std::string finalFileName = dir + "/" + baseFilename; mitk::ImageWriter::Pointer imageWriter = mitk::ImageWriter::New(); //check if an extension is given, else use the defaul extension if( extension == "" ) { - MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName - << DEFAULTIMAGEEXTENSION; - extension = DEFAULTIMAGEEXTENSION; + MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName + << DEFAULTIMAGEEXTENSION; + extension = DEFAULTIMAGEEXTENSION; } // check if extension is suitable for writing image data if (!imageWriter->IsExtensionValid(extension)) { - MITK_WARN << extension << " extension is unknown. Extension set to default: " << finalFileName - << DEFAULTIMAGEEXTENSION; - extension = DEFAULTIMAGEEXTENSION; + MITK_WARN << extension << " extension is unknown. Extension set to default: " << finalFileName + << DEFAULTIMAGEEXTENSION; + extension = DEFAULTIMAGEEXTENSION; } try { - //write the data - imageWriter->SetInput(image); - imageWriter->SetFileName(finalFileName.c_str()); - imageWriter->SetExtension(extension.c_str()); - imageWriter->Write(); + //write the data + imageWriter->SetInput(image); + imageWriter->SetFileName(finalFileName.c_str()); + imageWriter->SetExtension(extension.c_str()); + imageWriter->Write(); } catch ( std::exception& e ) { - MITK_ERROR << " during attempt to write '" << finalFileName + extension << "' Exception says:"; - MITK_ERROR << e.what(); - mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); + MITK_ERROR << " during attempt to write '" << finalFileName + extension << "' Exception says:"; + MITK_ERROR << e.what(); + mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); } return true; -} + } -bool IOUtil::SaveSurface(Surface::Pointer surface, const std::string& path) -{ + bool IOUtil::SaveSurface(Surface::Pointer surface, const std::string& path) + { std::string dir = itksys::SystemTools::GetFilenamePath( path ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( path ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( path ); if (dir == "") dir = "."; std::string finalFileName = dir + "/" + baseFilename; if (extension == "") // if no extension has been set we use the default extension { - MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName - << DEFAULTSURFACEEXTENSION; - extension = DEFAULTSURFACEEXTENSION; + MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName + << DEFAULTSURFACEEXTENSION; + extension = DEFAULTSURFACEEXTENSION; } try { - finalFileName += extension; - if(extension == ".stl" ) - { - mitk::SurfaceVtkWriter::Pointer surfaceWriter = mitk::SurfaceVtkWriter::New(); - - // check if surface actually consists of triangles; if not, the writer will not do anything; so, convert to triangles... - vtkPolyData* polys = surface->GetVtkPolyData(); - if( polys->GetNumberOfStrips() > 0 ) - { - vtkSmartPointer triangleFilter = vtkSmartPointer::New(); - triangleFilter->SetInputData(polys); - triangleFilter->Update(); - polys = triangleFilter->GetOutput(); - polys->Register(NULL); - surface->SetVtkPolyData(polys); - } - surfaceWriter->SetInput( surface ); - surfaceWriter->SetFileName( finalFileName.c_str() ); - surfaceWriter->GetVtkWriter()->SetFileTypeToBinary(); - surfaceWriter->Write(); - } - else if(extension == ".vtp") - { - mitk::SurfaceVtkWriter::Pointer surfaceWriter = mitk::SurfaceVtkWriter::New(); - surfaceWriter->SetInput( surface ); - surfaceWriter->SetFileName( finalFileName.c_str() ); - surfaceWriter->GetVtkWriter()->SetDataModeToBinary(); - surfaceWriter->Write(); - } - else if(extension == ".vtk") - { - mitk::SurfaceVtkWriter::Pointer surfaceWriter = mitk::SurfaceVtkWriter::New(); - surfaceWriter->SetInput( surface ); - surfaceWriter->SetFileName( finalFileName.c_str() ); - surfaceWriter->Write(); - } - else + finalFileName += extension; + if(extension == ".stl" ) + { + mitk::SurfaceVtkWriter::Pointer surfaceWriter = mitk::SurfaceVtkWriter::New(); + + // check if surface actually consists of triangles; if not, the writer will not do anything; so, convert to triangles... + vtkPolyData* polys = surface->GetVtkPolyData(); + if( polys->GetNumberOfStrips() > 0 ) { - // file extension not suitable for writing specified data type - MITK_ERROR << "File extension is not suitable for writing'" << finalFileName; - mitkThrow() << "An exception occured during writing the file " << finalFileName << - ". File extension " << extension << " is not suitable for writing."; + vtkSmartPointer triangleFilter = vtkSmartPointer::New(); + triangleFilter->SetInputData(polys); + triangleFilter->Update(); + polys = triangleFilter->GetOutput(); + polys->Register(NULL); + surface->SetVtkPolyData(polys); } + surfaceWriter->SetInput( surface ); + surfaceWriter->SetFileName( finalFileName.c_str() ); + surfaceWriter->GetVtkWriter()->SetFileTypeToBinary(); + surfaceWriter->Write(); + } + else if(extension == ".vtp") + { + mitk::SurfaceVtkWriter::Pointer surfaceWriter = mitk::SurfaceVtkWriter::New(); + surfaceWriter->SetInput( surface ); + surfaceWriter->SetFileName( finalFileName.c_str() ); + surfaceWriter->GetVtkWriter()->SetDataModeToBinary(); + surfaceWriter->Write(); + } + else if(extension == ".vtk") + { + mitk::SurfaceVtkWriter::Pointer surfaceWriter = mitk::SurfaceVtkWriter::New(); + surfaceWriter->SetInput( surface ); + surfaceWriter->SetFileName( finalFileName.c_str() ); + surfaceWriter->Write(); + } + else + { + // file extension not suitable for writing specified data type + MITK_ERROR << "File extension is not suitable for writing'" << finalFileName; + mitkThrow() << "An exception occured during writing the file " << finalFileName << + ". File extension " << extension << " is not suitable for writing."; + } } catch(std::exception& e) { - MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:"; - MITK_ERROR << e.what(); - mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); + MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:"; + MITK_ERROR << e.what(); + mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); } return true; -} + } -bool IOUtil::SavePointSet(PointSet::Pointer pointset, const std::string& path) -{ + bool IOUtil::SavePointSet(PointSet::Pointer pointset, const std::string& path) + { mitk::PointSetWriter::Pointer pointSetWriter = mitk::PointSetWriter::New(); std::string dir = itksys::SystemTools::GetFilenamePath( path ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( path ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( path ); if (dir == "") dir = "."; std::string finalFileName = dir + "/" + baseFilename; if (extension == "") // if no extension has been entered manually into the filename { - MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName - << DEFAULTPOINTSETEXTENSION; - extension = DEFAULTPOINTSETEXTENSION; + MITK_WARN << extension << " extension is not set. Extension set to default: " << finalFileName + << DEFAULTPOINTSETEXTENSION; + extension = DEFAULTPOINTSETEXTENSION; } // check if extension is valid if (!pointSetWriter->IsExtensionValid(extension)) { - MITK_WARN << extension << " extension is unknown. Extension set to default: " << finalFileName - << DEFAULTPOINTSETEXTENSION; - extension = DEFAULTPOINTSETEXTENSION; + MITK_WARN << extension << " extension is unknown. Extension set to default: " << finalFileName + << DEFAULTPOINTSETEXTENSION; + extension = DEFAULTPOINTSETEXTENSION; } try { - pointSetWriter->SetInput( pointset ); - finalFileName += extension; - pointSetWriter->SetFileName( finalFileName.c_str() ); - pointSetWriter->Update(); + pointSetWriter->SetInput( pointset ); + finalFileName += extension; + pointSetWriter->SetFileName( finalFileName.c_str() ); + pointSetWriter->Update(); } catch( std::exception& e ) { - MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:"; - MITK_ERROR << e.what(); - mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); + MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:"; + MITK_ERROR << e.what(); + mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); } return true; -} + } -bool IOUtil::SaveBaseData( mitk::BaseData* data, const std::string& path ) -{ - if (data == NULL || path.empty()) return false; + bool IOUtil::SaveBaseData( mitk::BaseData* data, const std::string& path ) + { + if (data == NULL || path.empty()) return false; - std::string dir = itksys::SystemTools::GetFilenamePath( path ); - std::string baseFilename = itksys::SystemTools::GetFilenameWithoutExtension( path ); - std::string extension = itksys::SystemTools::GetFilenameExtension( path ); - if (dir == "") - dir = "."; - std::string fileNameWithoutExtension = dir + "/" + baseFilename; + std::string dir = itksys::SystemTools::GetFilenamePath( path ); + std::string baseFilename = itksys::SystemTools::GetFilenameWithoutExtension( path ); + std::string extension = itksys::SystemTools::GetFilenameExtension( path ); + if (dir == "") + dir = "."; + std::string fileNameWithoutExtension = dir + "/" + baseFilename; - mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters(); + mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters(); - for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it) - { - if ( (*it)->CanWriteBaseDataType(data) ) + for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it) { - // Ensure a valid filename - if(baseFilename=="") - { - baseFilename = (*it)->GetDefaultFilename(); - } - // Check if an extension exists already and if not, append the default extension - if (extension=="" ) + if ( (*it)->CanWriteBaseDataType(data) ) { - extension=(*it)->GetDefaultExtension(); - } - else - { - if (!(*it)->IsExtensionValid(extension)) + // Ensure a valid filename + if(baseFilename=="") { - MITK_WARN << extension << " extension is unknown"; - continue; + baseFilename = (*it)->GetDefaultFilename(); + } + // Check if an extension exists already and if not, append the default extension + if (extension=="" ) + { + extension=(*it)->GetDefaultExtension(); + } + else + { + if (!(*it)->IsExtensionValid(extension)) + { + MITK_WARN << extension << " extension is unknown"; + continue; + } } - } - std::string finalFileName = fileNameWithoutExtension + extension; - try - { - (*it)->SetFileName( finalFileName.c_str() ); - (*it)->DoWrite( data ); - return true; - } - catch( const std::exception& e ) - { - MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:"; - MITK_ERROR << e.what(); - mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); + std::string finalFileName = fileNameWithoutExtension + extension; + try + { + (*it)->SetFileName( finalFileName.c_str() ); + (*it)->DoWrite( data ); + return true; + } + catch( const std::exception& e ) + { + MITK_ERROR << " during attempt to write '" << finalFileName << "' Exception says:"; + MITK_ERROR << e.what(); + mitkThrow() << "An exception occured during writing the file " << finalFileName << ". Exception says " << e.what(); + } } } - } - - return false; -} -} + return false; + } +} \ No newline at end of file diff --git a/Core/Code/IO/mitkIOUtil.h b/Core/Code/IO/mitkIOUtil.h index 215111d810..41f991ec96 100644 --- a/Core/Code/IO/mitkIOUtil.h +++ b/Core/Code/IO/mitkIOUtil.h @@ -1,267 +1,274 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKIOUTIL_H #define MITKIOUTIL_H #include #include #include #include #include #include namespace mitk { /** * \ingroup IO * * \brief A utility class to load and save data from/to the local file system. * * This method LoadFiles queries the MITK Micro Services registry for registered mitk::IDataNodeReader service * instances. The service instance with the highest ranking will be asked first to load the * given file. On error (exception thrown) or if no mitk::DataNode was constructed, the next * service instance is used. * * The methods LoadImage, LoadSurface, and LoadPointSet are convenience methods for general loading of * the three main data types in MITK. They all use the more generic method LoadDataNode. * * The methods SaveImage, SaveSurface, and SurfacePointSet are also meant for convenience (e.g. during testing). * Currently, there is no generic way to save a generic DataNode with an appropriate format. Thus, every method * initializes the corresponding instance of the special writer for the data type. * * \see mitk::IDataNodeReader */ class MITK_CORE_EXPORT IOUtil { public: /** * Get the file system path where the running executable is located. * * @return The location of the currently running executable, without the filename. */ static std::string GetProgramPath(); /** * Get the default temporary path. * * @return The default path for temporary data. */ static std::string GetTempPath(); + /** + * Returns the Directory Seperator for the current OS. + * + * @return the Directory Seperator for the current OS, i.e. "\\" for Windows and "/" otherwise. + */ + static std::string GetDirectorySeparator(); + /** * Create and open a temporary file. * * This method generates a unique temporary filename from \c templateName, creates * and opens the file using the output stream \c tmpStream and returns the name of * the newly create file. * * The \c templateName argument must contain six consective 'X' characters ("XXXXXX") * and these are replaced with a string that makes the filename unique. * * The file is created with read and write permissions for owner only. * * @param tmpStream The output stream for writing to the temporary file. * @param templateName An optional template for the filename. * @param path An optional path where the temporary file should be created. Defaults * to the default temp path as returned by GetTempPath(). * @return The filename of the created temporary file. * * @throw mitk::Exception if the temporary file could not be created. */ static std::string CreateTemporaryFile(std::ofstream& tmpStream, const std::string& templateName = "XXXXXX", std::string path = std::string()); /** * Create and open a temporary file. * * This method generates a unique temporary filename from \c templateName, creates * and opens the file using the output stream \c tmpStream and the specified open * mode \c mode and returns the name of the newly create file. The open mode is always * OR'd with \begin{code}std::ios_base::out | std::ios_base::trunc\end{code}. * * The \c templateName argument must contain six consective 'X' characters ("XXXXXX") * and these are replaced with a string that makes the filename unique. * * The file is created with read and write permissions for owner only. * * @param tmpStream The output stream for writing to the temporary file. * @param mode The open mode for the temporary file stream. * @param templateName An optional template for the filename. * @param path An optional path where the temporary file should be created. Defaults * to the default temp path as returned by GetTempPath(). * @return The filename of the created temporary file. * * @throw mitk::Exception if the temporary file could not be created. */ static std::string CreateTemporaryFile(std::ofstream& tmpStream, std::ios_base::openmode mode, const std::string& templateName = "XXXXXX", std::string path = std::string()); /** * Creates an empty temporary file. * * This method generates a unique temporary filename from \c templateName and creates * this file. * * The file is created with read and write permissions for owner only. * * --- * This version is potentially unsafe because the created temporary file is not kept open * and could be used by another process between calling this method and opening the returned * file path for reading or writing. * --- * * @return The filename of the created temporary file. * @param templateName An optional template for the filename. * @param path An optional path where the temporary file should be created. Defaults * to the default temp path as returned by GetTempPath(). * @throw mitk::Exception if the temporary file could not be created. */ static std::string CreateTemporaryFile(const std::string& templateName = "XXXXXX", std::string path = std::string()); /** * Create a temporary directory. * * This method generates a uniquely named temporary directory from \c templateName. * The last set of six consecutive 'X' characters in \c templateName is replaced * with a string that makes the directory name unique. * * The directory is created with read, write and executable permissions for owner only. * * @param templateName An optional template for the directory name. * @param path An optional path where the temporary directory should be created. Defaults * to the default temp path as returned by GetTempPath(). * @return The filename of the created temporary file. * * @throw mitk::Exception if the temporary directory could not be created. */ static std::string CreateTemporaryDirectory(const std::string& templateName = "XXXXXX", std::string path = std::string()); /** * Load a files in fileNames and add the constructed mitk::DataNode instances * to the mitk::DataStorage storage * * \param fileNames A list (vector) of absolute file name paths. * \param storage The data storage to which the constructed data nodes are added. * \return The number of added mitk::DataNode instances. */ static int LoadFiles(const std::vector&fileNames, DataStorage& storage); /** * This method will create a new mitk::DataStorage instance and pass it to * LoadFiles(std::vector,DataStorage). * * \param fileNames A list (vector) of absolute file name paths. * \return The new mitk::DataStorage containing the constructed data nodes. * * \see LoadFiles(std::vector,DataStorage) */ static DataStorage::Pointer LoadFiles(const std::vector& fileNames); /** * @brief Create a BaseData object from the given file. * @param path The path to the file including file name and file extension. * @throws mitk::Exception In case of an error when reading the file. * @return Returns the created BaseData object. */ static mitk::BaseData::Pointer LoadBaseData(const std::string& path); /** * @brief LoadDataNode Method to load an arbitrary DataNode. * @param path The path to the file including file name and file extension. * @throws mitk::Exception This exception is thrown when the DataNodeFactory is not able to read/find the file * or the DataNode is NULL. * @return Returns the DataNode. */ static mitk::DataNode::Pointer LoadDataNode(const std::string& path); /** * @brief LoadImage Convenience method to load an arbitrary mitkImage. * @param path The path to the image including file name and file extension. * @throws mitk::Exception This exception is thrown when the Image is NULL. * @return Returns the mitkImage. */ static mitk::Image::Pointer LoadImage(const std::string& path); /** * @brief LoadSurface Convenience method to load an arbitrary mitkSurface. * @param path The path to the surface including file name and file extension. * @throws mitk::Exception This exception is thrown when the Surface is NULL. * @return Returns the mitkSurface. */ static mitk::Surface::Pointer LoadSurface(const std::string& path); /** * @brief LoadPointSet Convenience method to load an arbitrary mitkPointSet. * @param path The path to the pointset including file name and file extension (currently, only .mps is supported). * @throws mitk::Exception This exception is thrown when the PointSet is NULL. * @return Returns the mitkPointSet. */ static mitk::PointSet::Pointer LoadPointSet(const std::string& path); /** * @brief SaveImage Convenience method to save an arbitrary mitkImage. * @param path The path to the image including file name and file extension. * If not extention is set, the default value (defined in DEFAULTIMAGEEXTENSION) is used. * @param image The image to save. * @throws mitk::Exception This exception is thrown when the writer is not able to write the image. * @return Returns true for success else false. */ static bool SaveImage(mitk::Image::Pointer image, const std::string& path); /** * @brief SaveBaseData Convenience method to save arbitrary baseData. * @param path The path to the image including file name and file extension. * If not extention is set, the default value (defined in DEFAULTIMAGEEXTENSION) is used. * @param data The data to save. * @throws mitk::Exception This exception is thrown when the writer is not able to write the image. * @return Returns true for success else false. */ static bool SaveBaseData(mitk::BaseData* data, const std::string& path); /** * @brief SaveSurface Convenience method to save an arbitrary mitkSurface. * @param path The path to the surface including file name and file extension. * If not extention is set, the default value (defined in DEFAULTSURFACEEXTENSION) is used. * @throws mitk::Exception This exception is thrown when the writer is not able to write the surface. * or if the fileextension is not suitable for writing. * @return Returns true for success else false. */ static bool SaveSurface(mitk::Surface::Pointer surface, const std::string& path); /** * @brief SavePointSet Convenience method to save an mitkPointSet. * @param path The path to the pointset including file name and file extension (currently, only .mps is supported). * If not extention is set, the default value (defined in DEFAULTPOINTSETEXTENSION) is used. * @throws mitk::Exception This exception is thrown when the writer is not able to write the pointset. * @return Returns true for success else false. */ static bool SavePointSet(mitk::PointSet::Pointer pointset, const std::string& path); static const std::string DEFAULTIMAGEEXTENSION; static const std::string DEFAULTSURFACEEXTENSION; static const std::string DEFAULTPOINTSETEXTENSION; }; } #endif // MITKIOUTIL_H