diff --git a/Core/Code/IO/mitkFileReaderSelector.cpp b/Core/Code/IO/mitkFileReaderSelector.cpp index b82a53ab83..58db436d77 100644 --- a/Core/Code/IO/mitkFileReaderSelector.cpp +++ b/Core/Code/IO/mitkFileReaderSelector.cpp @@ -1,294 +1,299 @@ /*=================================================================== 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 "mitkFileReaderSelector.h" #include #include #include #include #include #include namespace mitk { struct FileReaderSelector::Item::Impl : us::SharedData { Impl() : m_FileReader(NULL) , m_ConfidenceLevel(IFileReader::Unsupported) , m_Id(-1) {} us::ServiceReference m_FileReaderRef; IFileReader* m_FileReader; IFileReader::ConfidenceLevel m_ConfidenceLevel; MimeType m_MimeType; long m_Id; }; struct FileReaderSelector::Impl : us::SharedData { Impl() : m_BestId(-1) , m_SelectedId(m_BestId) {} Impl(const Impl& other) : us::SharedData(other) , m_BestId(-1) , m_SelectedId(m_BestId) {} FileReaderRegistry m_ReaderRegistry; std::map m_Items; std::vector m_MimeTypes; long m_BestId; long m_SelectedId; }; FileReaderSelector::FileReaderSelector(const FileReaderSelector& other) : m_Data(other.m_Data) { } FileReaderSelector::FileReaderSelector(const std::string& path) : m_Data(new Impl) { mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); // Get all mime types and associated readers for the given file path m_Data->m_MimeTypes = mimeTypeProvider->GetMimeTypesForFile(path); if (m_Data->m_MimeTypes.empty()) return; for (std::vector::const_iterator mimeTypeIter = m_Data->m_MimeTypes.begin(), mimeTypeIterEnd = m_Data->m_MimeTypes.end(); mimeTypeIter != mimeTypeIterEnd; ++mimeTypeIter) { std::vector refs = m_Data->m_ReaderRegistry.GetReferences(*mimeTypeIter); for (std::vector::const_iterator readerIter = refs.begin(), iterEnd = refs.end(); readerIter != iterEnd; ++readerIter) { IFileReader* reader = m_Data->m_ReaderRegistry.GetReader(*readerIter); if (reader == NULL) continue; try { reader->SetInput(path); IFileReader::ConfidenceLevel confidenceLevel = reader->GetConfidenceLevel(); std::cout << confidenceLevel << std::endl; if (confidenceLevel == IFileReader::Unsupported) { continue; } Item item; item.d->m_FileReaderRef = *readerIter; item.d->m_FileReader = reader; item.d->m_ConfidenceLevel = confidenceLevel; item.d->m_MimeType = *mimeTypeIter; item.d->m_Id = us::any_cast(readerIter->GetProperty(us::ServiceConstants::SERVICE_ID())); m_Data->m_Items.insert(std::make_pair(item.d->m_Id, item)); //m_Data->m_MimeTypes.insert(mimeType); } catch (const us::BadAnyCastException& e) { MITK_WARN << "Unexpected: " << e.what(); } catch (const std::exception& e) { // Log the error but continue MITK_WARN << "IFileWriter::GetConfidenceLevel exception: " << e.what(); } } } // get the "best" reader if (!m_Data->m_Items.empty()) { std::set sortedItems; for (std::map::const_iterator iter = m_Data->m_Items.begin(), iterEnd = m_Data->m_Items.end(); iter != iterEnd; ++iter) { sortedItems.insert(iter->second); } m_Data->m_BestId = sortedItems.rbegin()->GetServiceId(); m_Data->m_SelectedId = m_Data->m_BestId; } } FileReaderSelector::~FileReaderSelector() { } FileReaderSelector& FileReaderSelector::operator=(const FileReaderSelector& other) { m_Data = other.m_Data; return *this; } +bool FileReaderSelector::IsEmpty() const +{ + return m_Data->m_Items.empty(); +} + std::vector FileReaderSelector::GetMimeTypes() const { return m_Data->m_MimeTypes; } std::vector FileReaderSelector::Get() const { std::vector result; for (std::map::const_iterator iter = m_Data->m_Items.begin(), iterEnd = m_Data->m_Items.end(); iter != iterEnd; ++iter) { result.push_back(iter->second); } std::sort(result.begin(), result.end()); return result; } FileReaderSelector::Item FileReaderSelector::Get(long id) const { std::map::const_iterator iter = m_Data->m_Items.find(id); if (iter != m_Data->m_Items.end()) { return iter->second; } return Item(); } FileReaderSelector::Item FileReaderSelector::GetDefault() const { return Get(m_Data->m_BestId); } long FileReaderSelector::GetDefaultId() const { return m_Data->m_BestId; } FileReaderSelector::Item FileReaderSelector::GetSelected() const { return Get(m_Data->m_SelectedId); } long FileReaderSelector::GetSelectedId() const { return m_Data->m_SelectedId; } bool FileReaderSelector::Select(const FileReaderSelector::Item& item) { return Select(item.d->m_Id); } bool FileReaderSelector::Select(long id) { if (id > -1) { if (m_Data->m_Items.find(id) == m_Data->m_Items.end()) { return false; } m_Data->m_SelectedId = id; return true; } return false; } void FileReaderSelector::Swap(FileReaderSelector& fws) { m_Data.Swap(fws.m_Data); } FileReaderSelector::Item::Item(const FileReaderSelector::Item& other) : d(other.d) { } FileReaderSelector::Item::~Item() { } FileReaderSelector::Item& FileReaderSelector::Item::operator=(const FileReaderSelector::Item& other) { d = other.d; return *this; } IFileReader* FileReaderSelector::Item::GetReader() const { return d->m_FileReader; } std::string FileReaderSelector::Item::GetDescription() const { us::Any descr = d->m_FileReaderRef.GetProperty(IFileReader::PROP_DESCRIPTION()); if (descr.Empty()) return std::string(); return descr.ToString(); } IFileReader::ConfidenceLevel FileReaderSelector::Item::GetConfidenceLevel() const { return d->m_ConfidenceLevel; } MimeType FileReaderSelector::Item::GetMimeType() const { return d->m_MimeType; } us::ServiceReference FileReaderSelector::Item::GetReference() const { return d->m_FileReaderRef; } long FileReaderSelector::Item::GetServiceId() const { return d->m_Id; } bool FileReaderSelector::Item::operator<(const FileReaderSelector::Item& other) const { // sort by confidence level first (ascending) if (d->m_ConfidenceLevel == other.d->m_ConfidenceLevel) { // sort by mime-type ranking if (d->m_MimeType < other.d->m_MimeType) { return true; } else if (other.d->m_MimeType < d->m_MimeType) { return false; } else { // sort by file writer service ranking return d->m_FileReaderRef < other.d->m_FileReaderRef; } } return d->m_ConfidenceLevel < other.d->m_ConfidenceLevel; } FileReaderSelector::Item::Item() : d(new Impl()) {} void swap(FileReaderSelector& frs1, FileReaderSelector& frs2) { frs1.Swap(frs2); } } diff --git a/Core/Code/IO/mitkFileReaderSelector.h b/Core/Code/IO/mitkFileReaderSelector.h index ac13038252..b6f8cba061 100644 --- a/Core/Code/IO/mitkFileReaderSelector.h +++ b/Core/Code/IO/mitkFileReaderSelector.h @@ -1,113 +1,115 @@ /*=================================================================== 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 MITKFILEREADERSELECTOR_H #define MITKFILEREADERSELECTOR_H #include #include #include #include #include namespace mitk { class BaseData; class MITK_CORE_EXPORT FileReaderSelector { public: class MITK_CORE_EXPORT Item { public: Item(const Item& other); ~Item(); Item& operator=(const Item& other); IFileReader* GetReader() const; std::string GetDescription() const; IFileReader::ConfidenceLevel GetConfidenceLevel() const; MimeType GetMimeType() const; us::ServiceReference GetReference() const; long GetServiceId() const; bool operator<(const Item& other) const; private: friend class FileReaderSelector; Item(); struct Impl; us::SharedDataPointer d; }; FileReaderSelector(const FileReaderSelector& other); FileReaderSelector(const std::string& path); ~FileReaderSelector(); FileReaderSelector& operator=(const FileReaderSelector& other); + bool IsEmpty() const; + std::vector GetMimeTypes() const; /** * @brief Get a sorted list of file reader items. * *
    *
  1. Confidence level (ascending)
  2. *
  3. MimeType ordering (ascending)
  4. *
  5. File Reader service ranking (ascending)
  6. *
* * This means the best matching item is at the back of the returned * container. * * @return */ std::vector Get() const; Item Get(long id) const; Item GetDefault() const; long GetDefaultId() const; Item GetSelected() const; long GetSelectedId() const; bool Select(const Item& item); bool Select(long id); void Swap(FileReaderSelector& fws); private: struct Impl; us::ExplicitlySharedDataPointer m_Data; }; void swap(FileReaderSelector& fws1, FileReaderSelector& fws2); } #endif // MITKFILEREADERSELECTOR_H diff --git a/Core/Code/IO/mitkFileWriterSelector.cpp b/Core/Code/IO/mitkFileWriterSelector.cpp index 540089c893..62efdc562d 100644 --- a/Core/Code/IO/mitkFileWriterSelector.cpp +++ b/Core/Code/IO/mitkFileWriterSelector.cpp @@ -1,336 +1,359 @@ /*=================================================================== 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 "mitkFileWriterSelector.h" #include #include #include #include #include #include #include +#include + #include #include #include namespace mitk { struct FileWriterSelector::Item::Impl : us::SharedData { Impl() : m_FileWriter(NULL) , m_ConfidenceLevel(IFileWriter::Unsupported) , m_BaseDataIndex(0) , m_Id(-1) {} us::ServiceReference m_FileWriterRef; IFileWriter* m_FileWriter; IFileWriter::ConfidenceLevel m_ConfidenceLevel; std::size_t m_BaseDataIndex; MimeType m_MimeType; long m_Id; }; struct FileWriterSelector::Impl : us::SharedData { Impl() : m_BestId(-1) , m_SelectedId(m_BestId) {} Impl(const Impl& other) : us::SharedData(other) , m_BestId(-1) , m_SelectedId(m_BestId) {} FileWriterRegistry m_WriterRegistry; std::map m_Items; std::set m_MimeTypes; long m_BestId; long m_SelectedId; }; FileWriterSelector::FileWriterSelector(const FileWriterSelector& other) : m_Data(other.m_Data) { } -FileWriterSelector::FileWriterSelector(const BaseData* baseData, const std::string& destMimeType) +FileWriterSelector::FileWriterSelector(const BaseData* baseData, const std::string& mimeType, + const std::string& path) : m_Data(new Impl) { mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); + std::string destMimeType = mimeType; + if (destMimeType.empty() && !path.empty()) + { + // try to derive a mime-type from the extension + std::string ext = itksys::SystemTools::GetFilenameExtension(path); + if (ext.size() > 1) + { + std::vector mimeTypes = mimeTypeProvider->GetMimeTypesForExtension(ext.substr(1)); + if (!mimeTypes.empty()) + { + destMimeType = mimeTypes.front().GetName(); + } + } + } + std::vector classHierarchy = baseData->GetClassHierarchy(); // Get all writers and their mime types for the given base data type std::vector refs = m_Data->m_WriterRegistry.GetReferences(baseData, destMimeType); us::ServiceReference bestRef; for (std::vector::const_iterator iter = refs.begin(), iterEnd = refs.end(); iter != iterEnd; ++iter) { std::string mimeTypeName = iter->GetProperty(IFileWriter::PROP_MIMETYPE()).ToString(); if (!mimeTypeName.empty()) { MimeType mimeType = mimeTypeProvider->GetMimeTypeForName(mimeTypeName); if (mimeType.IsValid()) { // There is a registered mime-type for this writer. Now get the confidence level // of this writer for writing the given base data object. IFileWriter* writer = m_Data->m_WriterRegistry.GetWriter(*iter); if (writer == NULL) continue; try { writer->SetInput(baseData); IFileWriter::ConfidenceLevel confidenceLevel = writer->GetConfidenceLevel(); std::cout << confidenceLevel << std::endl; if (confidenceLevel == IFileWriter::Unsupported) { continue; } std::string baseDataType = iter->GetProperty(IFileWriter::PROP_BASEDATA_TYPE()).ToString(); std::vector::iterator idxIter = std::find(classHierarchy.begin(), classHierarchy.end(), baseDataType); std::size_t baseDataIndex = std::numeric_limits::max(); if (idxIter != classHierarchy.end()) { baseDataIndex = std::distance(classHierarchy.begin(), idxIter); } Item item; item.d->m_FileWriterRef = *iter; item.d->m_FileWriter = writer; item.d->m_ConfidenceLevel = confidenceLevel; item.d->m_BaseDataIndex = baseDataIndex; item.d->m_MimeType = mimeType; item.d->m_Id = us::any_cast(iter->GetProperty(us::ServiceConstants::SERVICE_ID())); m_Data->m_Items.insert(std::make_pair(item.d->m_Id, item)); m_Data->m_MimeTypes.insert(mimeType); if (!bestRef || bestRef < *iter) { bestRef = *iter; } } catch (const us::BadAnyCastException& e) { MITK_WARN << "Unexpected: " << e.what(); } catch (const std::exception& e) { // Log the error but continue MITK_WARN << "IFileWriter::GetConfidenceLevel exception: " << e.what(); } } } } if (bestRef) { try { m_Data->m_BestId = us::any_cast(bestRef.GetProperty(us::ServiceConstants::SERVICE_ID())); m_Data->m_SelectedId = m_Data->m_BestId; } catch (const us::BadAnyCastException&) {} } } FileWriterSelector::~FileWriterSelector() { } FileWriterSelector& FileWriterSelector::operator=(const FileWriterSelector& other) { m_Data = other.m_Data; return *this; } +bool FileWriterSelector::IsEmpty() const +{ + return m_Data->m_Items.empty(); +} + std::vector FileWriterSelector::Get(const std::string& mimeType) const { std::vector result; for (std::map::const_iterator iter = m_Data->m_Items.begin(), iterEnd = m_Data->m_Items.end(); iter != iterEnd; ++iter) { if (mimeType.empty() || iter->second.GetMimeType().GetName() == mimeType) { result.push_back(iter->second); } } std::sort(result.begin(), result.end()); return result; } std::vector FileWriterSelector::Get() const { return Get(this->GetSelected().d->m_MimeType.GetName()); } FileWriterSelector::Item FileWriterSelector::Get(long id) const { std::map::const_iterator iter = m_Data->m_Items.find(id); if (iter != m_Data->m_Items.end()) { return iter->second; } return Item(); } FileWriterSelector::Item FileWriterSelector::GetDefault() const { return Get(m_Data->m_BestId); } long FileWriterSelector::GetDefaultId() const { return m_Data->m_BestId; } FileWriterSelector::Item FileWriterSelector::GetSelected() const { return Get(m_Data->m_SelectedId); } long FileWriterSelector::GetSelectedId() const { return m_Data->m_SelectedId; } bool FileWriterSelector::Select(const std::string& mimeType) { std::vector items = Get(mimeType); if (items.empty()) return false; return Select(items.back()); } bool FileWriterSelector::Select(const FileWriterSelector::Item& item) { return Select(item.d->m_Id); } bool FileWriterSelector::Select(long id) { if (id > -1) { if (m_Data->m_Items.find(id) == m_Data->m_Items.end()) { return false; } m_Data->m_SelectedId = id; return true; } return false; } std::vector FileWriterSelector::GetMimeTypes() const { std::vector result; result.reserve(m_Data->m_MimeTypes.size()); result.assign(m_Data->m_MimeTypes.begin(), m_Data->m_MimeTypes.end()); return result; } void FileWriterSelector::Swap(FileWriterSelector& fws) { m_Data.Swap(fws.m_Data); } FileWriterSelector::Item::Item(const FileWriterSelector::Item& other) : d(other.d) { } FileWriterSelector::Item::~Item() { } FileWriterSelector::Item& FileWriterSelector::Item::operator=(const FileWriterSelector::Item& other) { d = other.d; return *this; } IFileWriter* FileWriterSelector::Item::GetWriter() const { return d->m_FileWriter; } std::string FileWriterSelector::Item::GetDescription() const { us::Any descr = d->m_FileWriterRef.GetProperty(IFileWriter::PROP_DESCRIPTION()); if (descr.Empty()) return std::string(); return descr.ToString(); } IFileWriter::ConfidenceLevel FileWriterSelector::Item::GetConfidenceLevel() const { return d->m_ConfidenceLevel; } MimeType FileWriterSelector::Item::GetMimeType() const { return d->m_MimeType; } std::string FileWriterSelector::Item::GetBaseDataType() const { us::Any any = d->m_FileWriterRef.GetProperty(IFileWriter::PROP_BASEDATA_TYPE()); if (any.Empty()) return std::string(); return any.ToString(); } us::ServiceReference FileWriterSelector::Item::GetReference() const { return d->m_FileWriterRef; } long FileWriterSelector::Item::GetServiceId() const { return d->m_Id; } bool FileWriterSelector::Item::operator<(const FileWriterSelector::Item& other) const { // sort by confidence level first (ascending) if (d->m_ConfidenceLevel == other.d->m_ConfidenceLevel) { // sort by class hierarchy index (writers for more derived // based data types are considered a better match) if (d->m_BaseDataIndex == other.d->m_BaseDataIndex) { // sort by file writer service ranking return d->m_FileWriterRef < other.d->m_FileWriterRef; } return other.d->m_BaseDataIndex < d->m_BaseDataIndex; } return d->m_ConfidenceLevel < other.d->m_ConfidenceLevel; } FileWriterSelector::Item::Item() : d(new Impl()) {} void swap(FileWriterSelector& fws1, FileWriterSelector& fws2) { fws1.Swap(fws2); } } diff --git a/Core/Code/IO/mitkFileWriterSelector.h b/Core/Code/IO/mitkFileWriterSelector.h index edfb084501..bce7143eb7 100644 --- a/Core/Code/IO/mitkFileWriterSelector.h +++ b/Core/Code/IO/mitkFileWriterSelector.h @@ -1,125 +1,128 @@ /*=================================================================== 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 MITKFILEWRITERSELECTOR_H #define MITKFILEWRITERSELECTOR_H #include #include #include #include #include namespace mitk { class BaseData; class MITK_CORE_EXPORT FileWriterSelector { public: class MITK_CORE_EXPORT Item { public: Item(const Item& other); ~Item(); Item& operator=(const Item& other); IFileWriter* GetWriter() const; std::string GetDescription() const; IFileWriter::ConfidenceLevel GetConfidenceLevel() const; MimeType GetMimeType() const; std::string GetBaseDataType() const; us::ServiceReference GetReference() const; long GetServiceId() const; bool operator<(const Item& other) const; private: friend class FileWriterSelector; Item(); struct Impl; us::SharedDataPointer d; }; FileWriterSelector(const FileWriterSelector& other); - FileWriterSelector(const BaseData* baseData, const std::string& destMimeType = std::string()); + FileWriterSelector(const BaseData* baseData, const std::string& destMimeType = std::string(), + const std::string& path = std::string()); ~FileWriterSelector(); FileWriterSelector& operator=(const FileWriterSelector& other); + bool IsEmpty() const; + /** * @brief Get a sorted list of file writer info objects. * *
    *
  1. Confidence level (ascending)
  2. *
  3. File Writer service ranking (ascending)
  4. *
* * This means the best matching item is at the back of the returned * container. * * @param mimeType * @return */ std::vector Get(const std::string& mimeType) const; /** * @brief Get a sorted list of file writer info objects. * * The returned objects will have the same mime-type as the currently * selected item. * * @return Ordered list of file writer items. */ std::vector Get() const; Item Get(long id) const; Item GetDefault() const; long GetDefaultId() const; Item GetSelected() const; long GetSelectedId() const; bool Select(const std::string& mimeType); bool Select(const Item& item); bool Select(long id); std::vector GetMimeTypes() const; void Swap(FileWriterSelector& fws); private: struct Impl; us::ExplicitlySharedDataPointer m_Data; }; void swap(FileWriterSelector& fws1, FileWriterSelector& fws2); } #endif // MITKFILEWRITERSELECTOR_H diff --git a/Core/Code/IO/mitkIOUtil.cpp b/Core/Code/IO/mitkIOUtil.cpp index 54da62f0bd..35b16e1bdd 100644 --- a/Core/Code/IO/mitkIOUtil.cpp +++ b/Core/Code/IO/mitkIOUtil.cpp @@ -1,1088 +1,1072 @@ /*=================================================================== 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 #include #include #include #include #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. */ #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)); 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)); 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. */ #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)); 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)); 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 //************************************************************** // mitk::IOUtil method definitions namespace mitk { const std::string IOUtil::DEFAULTIMAGEEXTENSION = ".nrrd"; const std::string IOUtil::DEFAULTSURFACEEXTENSION = ".stl"; const std::string IOUtil::DEFAULTPOINTSETEXTENSION = ".mps"; struct IOUtil::Impl { struct FixedReaderOptionsFunctor : public ReaderOptionsFunctorBase { FixedReaderOptionsFunctor(const IFileReader::Options& options) : m_Options(options) {} virtual bool operator()(LoadInfo& loadInfo) { IFileReader* reader = loadInfo.m_ReaderSelector.GetSelected().GetReader(); if (reader) { reader->SetOptions(m_Options); } return false; } private: const IFileReader::Options& m_Options; }; struct FixedWriterOptionsFunctor : public WriterOptionsFunctorBase { FixedWriterOptionsFunctor(const IFileReader::Options& options) : m_Options(options) {} virtual bool operator()(SaveInfo& saveInfo) { IFileWriter* writer = saveInfo.m_WriterSelector.GetSelected().GetWriter(); if (writer) { writer->SetOptions(m_Options); } return false; } private: const IFileWriter::Options& m_Options; }; static BaseData::Pointer LoadBaseDataFromFile(const std::string& path); static void SetDefaultDataNodeProperties(mitk::DataNode* node, const std::string& filePath = std::string()); }; #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); } #elif defined(US_PLATFORM_APPLE) #include std::string IOUtil::GetProgramPath() { 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(); } #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); } #endif char IOUtil::GetDirectorySeparator() { #ifdef US_PLATFORM_WINDOWS return '\\'; #else return '/'; #endif } std::string IOUtil::GetTempPath() { static std::string result; if (result.empty()) { #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/"; #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(); } 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 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::string IOUtil::CreateTemporaryDirectory(const std::string& templateName, std::string path) { if (path.empty()) { path = GetTempPath(); } 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 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; } DataStorage::SetOfObjects::Pointer IOUtil::Load(const std::string& path, DataStorage& storage) { std::vector paths; paths.push_back(path); return Load(paths, storage); } DataStorage::SetOfObjects::Pointer IOUtil::Load(const std::string& path, const IFileReader::Options& options, DataStorage& storage) { std::vector loadInfos; loadInfos.push_back(LoadInfo(path)); DataStorage::SetOfObjects::Pointer nodeResult = DataStorage::SetOfObjects::New(); Impl::FixedReaderOptionsFunctor optionsCallback(options); std::string errMsg = Load(loadInfos, nodeResult, &storage, &optionsCallback); if (!errMsg.empty()) { mitkThrow() << errMsg; } return nodeResult; } std::vector IOUtil::Load(const std::string& path) { std::vector paths; paths.push_back(path); return Load(paths); } std::vector IOUtil::Load(const std::string& path, const IFileReader::Options& options) { std::vector loadInfos; loadInfos.push_back(LoadInfo(path)); Impl::FixedReaderOptionsFunctor optionsCallback(options); std::string errMsg = Load(loadInfos, NULL, NULL, &optionsCallback); if (!errMsg.empty()) { mitkThrow() << errMsg; } return loadInfos.front().m_Output; } DataStorage::SetOfObjects::Pointer IOUtil::Load(const std::vector& paths, DataStorage& storage) { DataStorage::SetOfObjects::Pointer nodeResult = DataStorage::SetOfObjects::New(); std::vector loadInfos; for (std::vector::const_iterator iter = paths.begin(), iterEnd = paths.end(); iter != iterEnd; ++iter) { LoadInfo loadInfo(*iter); loadInfos.push_back(loadInfo); } std::string errMsg = Load(loadInfos, nodeResult, &storage, NULL); if (!errMsg.empty()) { mitkThrow() << errMsg; } return nodeResult; } std::vector IOUtil::Load(const std::vector& paths) { std::vector result; std::vector loadInfos; for (std::vector::const_iterator iter = paths.begin(), iterEnd = paths.end(); iter != iterEnd; ++iter) { LoadInfo loadInfo(*iter); loadInfos.push_back(loadInfo); } std::string errMsg = Load(loadInfos, NULL, NULL, NULL); if (!errMsg.empty()) { mitkThrow() << errMsg; } for (std::vector::const_iterator iter = loadInfos.begin(), iterEnd = loadInfos.end(); iter != iterEnd; ++iter) { result.insert(result.end(), iter->m_Output.begin(), iter->m_Output.end()); } return result; } int IOUtil::LoadFiles(const std::vector &fileNames, DataStorage& ds) { return static_cast(Load(fileNames, ds)->Size()); } DataStorage::Pointer IOUtil::LoadFiles(const std::vector& fileNames) { mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); Load(fileNames, *ds); return ds.GetPointer(); } BaseData::Pointer IOUtil::LoadBaseData(const std::string& path) { return Impl::LoadBaseDataFromFile(path); } BaseData::Pointer IOUtil::Impl::LoadBaseDataFromFile(const std::string& path) { std::vector baseDataList = Load(path); // The Load(path) call above should throw an exception if nothing could be loaded assert(!baseDataList.empty()); return baseDataList.front(); } DataNode::Pointer IOUtil::LoadDataNode(const std::string& path) { BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(baseData); Impl::SetDefaultDataNodeProperties(node, path); return node; } Image::Pointer IOUtil::LoadImage(const std::string& path) { BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path); mitk::Image::Pointer image = dynamic_cast(baseData.GetPointer()); if(image.IsNull()) { mitkThrow() << path << " is not a mitk::Image but a " << baseData->GetNameOfClass(); } return image; } Surface::Pointer IOUtil::LoadSurface(const std::string& path) { BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path); mitk::Surface::Pointer surface = dynamic_cast(baseData.GetPointer()); if(surface.IsNull()) { mitkThrow() << path << " is not a mitk::Surface but a " << baseData->GetNameOfClass(); } return surface; } PointSet::Pointer IOUtil::LoadPointSet(const std::string& path) { BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path); mitk::PointSet::Pointer pointset = dynamic_cast(baseData.GetPointer()); if(pointset.IsNull()) { mitkThrow() << path << " is not a mitk::PointSet but a " << baseData->GetNameOfClass(); } return pointset; } std::string IOUtil::Load(std::vector& loadInfos, DataStorage::SetOfObjects* nodeResult, DataStorage* ds, ReaderOptionsFunctorBase* optionsCallback) { if (loadInfos.empty()) { return "No input files given"; } int filesToRead = loadInfos.size(); mitk::ProgressBar::GetInstance()->AddStepsToDo(2*filesToRead); std::string errMsg; std::map usedReaderItems; for(std::vector::iterator infoIter = loadInfos.begin(), infoIterEnd = loadInfos.end(); infoIter != infoIterEnd; ++infoIter) { std::vector readers = infoIter->m_ReaderSelector.Get(); if (readers.empty()) { errMsg += "No reader available for '" + infoIter->m_Path + "'\n"; continue; } bool callOptionsCallback = readers.size() > 1 || !readers.front().GetReader()->GetOptions().empty(); // check if we already used a reader which should be re-used std::vector currMimeTypes = infoIter->m_ReaderSelector.GetMimeTypes(); std::string selectedMimeType; for (std::vector::const_iterator mimeTypeIter = currMimeTypes.begin(), mimeTypeIterEnd = currMimeTypes.end(); mimeTypeIter != mimeTypeIterEnd; ++mimeTypeIter) { std::map::const_iterator oldSelectedItemIter = usedReaderItems.find(mimeTypeIter->GetName()); if (oldSelectedItemIter != usedReaderItems.end()) { // we found an already used item for a mime-type which is contained // in the current reader set, check all current readers if there service // id equals the old reader for (std::vector::const_iterator currReaderItem = readers.begin(), currReaderItemEnd = readers.end(); currReaderItem != currReaderItemEnd; ++currReaderItem) { if (currReaderItem->GetMimeType().GetName() == mimeTypeIter->GetName() && currReaderItem->GetServiceId() == oldSelectedItemIter->second.GetServiceId() && currReaderItem->GetConfidenceLevel() >= oldSelectedItemIter->second.GetConfidenceLevel()) { // okay, we used the same reader already, re-use its options selectedMimeType = mimeTypeIter->GetName(); callOptionsCallback = false; infoIter->m_ReaderSelector.Select(oldSelectedItemIter->second.GetServiceId()); infoIter->m_ReaderSelector.GetSelected().GetReader()->SetOptions( oldSelectedItemIter->second.GetReader()->GetOptions()); break; } } if (!selectedMimeType.empty()) break; } } if (callOptionsCallback && optionsCallback) { callOptionsCallback = (*optionsCallback)(*infoIter); if (!callOptionsCallback && !infoIter->m_Cancel) { usedReaderItems.erase(selectedMimeType); FileReaderSelector::Item selectedItem = infoIter->m_ReaderSelector.GetSelected(); usedReaderItems.insert(std::make_pair(selectedItem.GetMimeType().GetName(), selectedItem)); } } if (infoIter->m_Cancel) { errMsg += "Reading operation(s) cancelled."; break; } IFileReader* reader = infoIter->m_ReaderSelector.GetSelected().GetReader(); if (reader == NULL) { errMsg += "Unexpected NULL reader."; break; } MITK_INFO << "******* USING READER " << typeid(*reader).name() << "*********"; // Do the actual reading try { DataStorage::SetOfObjects::Pointer nodes; if (ds != NULL) { nodes = reader->Read(*ds); } else { nodes = DataStorage::SetOfObjects::New(); std::vector baseData = reader->Read(); for (std::vector::iterator iter = baseData.begin(); iter != baseData.end(); ++iter) { if (iter->IsNotNull()) { mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(*iter); nodes->InsertElement(nodes->Size(), node); } } } for (DataStorage::SetOfObjects::ConstIterator nodeIter = nodes->Begin(), nodeIterEnd = nodes->End(); nodeIter != nodeIterEnd; ++nodeIter) { const mitk::DataNode::Pointer& node = nodeIter->Value(); mitk::BaseData::Pointer data = node->GetData(); if (data.IsNull()) { continue; } mitk::StringProperty::Pointer pathProp = mitk::StringProperty::New(infoIter->m_Path); data->SetProperty("path", pathProp); infoIter->m_Output.push_back(data); if (nodeResult) { nodeResult->push_back(nodeIter->Value()); } } if (infoIter->m_Output.empty() || (nodeResult && nodeResult->Size() == 0)) { errMsg += "Unknown read error occurred reading " + infoIter->m_Path; } } catch (const std::exception& e) { errMsg += "Exception occured when reading file " + infoIter->m_Path + ":\n" + e.what() + "\n\n"; } mitk::ProgressBar::GetInstance()->Progress(2); --filesToRead; } if (!errMsg.empty()) { MITK_ERROR << errMsg; } mitk::ProgressBar::GetInstance()->Progress(2*filesToRead); return errMsg; } void IOUtil::Save(const BaseData* data, const std::string& path) { Save(data, path, IFileWriter::Options()); } void IOUtil::Save(const BaseData* data, const std::string& path, const IFileWriter::Options& options) { Save(data, std::string(), path, options); } void IOUtil::Save(const BaseData* data, const std::string& mimeType, const std::string& path, bool addExtension) { Save(data, mimeType, path, IFileWriter::Options(), addExtension); } void IOUtil::Save(const BaseData* data, const std::string& mimeType, const std::string& path, const IFileWriter::Options& options, bool addExtension) { std::string errMsg; if (options.empty()) { errMsg = Save(data, mimeType, path, NULL, addExtension); } else { Impl::FixedWriterOptionsFunctor optionsCallback(options); errMsg = Save(data, mimeType, path, &optionsCallback, addExtension); } if (!errMsg.empty()) { mitkThrow() << errMsg; } } void IOUtil::Save(std::vector& saveInfos) { std::string errMsg = Save(saveInfos, NULL); if (!errMsg.empty()) { mitkThrow() << errMsg; } } bool IOUtil::SaveImage(mitk::Image::Pointer image, const std::string& path) { Save(image, path); return true; } bool IOUtil::SaveSurface(Surface::Pointer surface, const std::string& path) { Save(surface, path); return true; } bool IOUtil::SavePointSet(PointSet::Pointer pointset, const std::string& path) { Save(pointset, path); return true; } bool IOUtil::SaveBaseData( mitk::BaseData* data, const std::string& path) { Save(data, path); return true; } -std::string IOUtil::Save(const BaseData* data, const std::string& mimeTypeN, const std::string& path, +std::string IOUtil::Save(const BaseData* data, const std::string& mimeTypeName, const std::string& path, WriterOptionsFunctorBase* optionsCallback, bool addExtension) { if (path.empty()) { return "No output filename given"; } mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); - std::string mimeTypeName = mimeTypeN; + MimeType mimeType = mimeTypeProvider->GetMimeTypeForName(mimeTypeName); + + SaveInfo saveInfo(data, mimeType, path); - // If no mime-type is provided, we try to get the mime-type from the - // highest ranked IFileWriter object for the given BaseData type - if (mimeTypeName.empty()) + if (saveInfo.m_WriterSelector.IsEmpty()) { - std::vector refs = us::GetModuleContext()->GetServiceReferences( - us::LDAPProp(us::ServiceConstants::OBJECTCLASS()) == us_service_interface_iid() && - us::LDAPProp(IFileWriter::PROP_BASEDATA_TYPE()) == data->GetNameOfClass()); - std::sort(refs.begin(), refs.end()); - if (!refs.empty()) - { - us::Any mimeProp = refs.back().GetProperty(IFileWriter::PROP_MIMETYPE()); - if (mimeProp.Type() == typeid(std::string)) - { - mimeTypeName = us::any_cast(mimeProp); - } - } + return std::string("No writer registered for type ") + data->GetNameOfClass() + + (mimeType.IsValid() ? (std::string(" and mime-type ") + mimeType.GetName()) : std::string()); } - MimeType mimeType = mimeTypeProvider->GetMimeTypeForName(mimeTypeName); - if (mimeType.IsValid()) + // Add an extension if not already specified + std::string ext = itksys::SystemTools::GetFilenameExtension(path); + if (ext.empty() && addExtension) { - std::string ext = itksys::SystemTools::GetFilenameExtension(path); - if (ext.empty() && addExtension) - { - ext = mimeType.GetExtensions().empty() ? std::string() : "." + mimeType.GetExtensions().front(); - } - std::vector infos; - infos.push_back(SaveInfo(data, mimeType, path + ext)); - return Save(infos, optionsCallback); + ext = saveInfo.m_MimeType.GetExtensions().empty() ? std::string() : "." + saveInfo.m_MimeType.GetExtensions().front(); } - return "The mime-type '" + mimeTypeName + "' is not registered"; + + std::vector infos; + infos.push_back(saveInfo); + return Save(infos, optionsCallback); } std::string IOUtil::Save(std::vector& saveInfos, WriterOptionsFunctorBase* optionsCallback) { if (saveInfos.empty()) { return "No data for saving available"; } int filesToWrite = saveInfos.size(); mitk::ProgressBar::GetInstance()->AddStepsToDo(2*filesToWrite); std::string errMsg; std::set usedSaveInfos; for (std::vector::iterator infoIter = saveInfos.begin(), infoIterEnd = saveInfos.end(); infoIter != infoIterEnd; ++infoIter) { const std::string baseDataType = infoIter->m_BaseData->GetNameOfClass(); std::vector writers = infoIter->m_WriterSelector.Get(); // Error out if no compatible Writer was found if (writers.empty()) { errMsg += std::string("No writer available for ") + baseDataType + " data.\n"; continue; } bool callOptionsCallback = writers.size() > 1 || !writers[0].GetWriter()->GetOptions().empty(); // check if we already used a writer for this base data type // which should be re-used std::set::const_iterator oldSaveInfoIter = usedSaveInfos.find(*infoIter); if (oldSaveInfoIter != usedSaveInfos.end()) { // we previously saved a base data object of the same data with the same mime-type, // check if the same writer is contained in the current writer set and if the // confidence level matches FileWriterSelector::Item oldSelectedItem = oldSaveInfoIter->m_WriterSelector.Get(oldSaveInfoIter->m_WriterSelector.GetSelectedId()); for (std::vector::const_iterator currWriterItem = writers.begin(), currWriterItemEnd = writers.end(); currWriterItem != currWriterItemEnd; ++currWriterItem) { if (currWriterItem->GetServiceId() == oldSelectedItem.GetServiceId() && currWriterItem->GetConfidenceLevel() >= oldSelectedItem.GetConfidenceLevel()) { // okay, we used the same writer already, re-use its options callOptionsCallback = false; infoIter->m_WriterSelector.Select(oldSaveInfoIter->m_WriterSelector.GetSelectedId()); infoIter->m_WriterSelector.GetSelected().GetWriter()->SetOptions( oldSelectedItem.GetWriter()->GetOptions()); break; } } } if (callOptionsCallback && optionsCallback) { callOptionsCallback = (*optionsCallback)(*infoIter); if (!callOptionsCallback && !infoIter->m_Cancel) { usedSaveInfos.erase(*infoIter); usedSaveInfos.insert(*infoIter); } } if (infoIter->m_Cancel) { errMsg += "Writing operation(s) cancelled."; break; } IFileWriter* writer = infoIter->m_WriterSelector.GetSelected().GetWriter(); if (writer == NULL) { errMsg += "Unexpected NULL writer."; break; } MITK_INFO << "******* USING WRITER " << typeid(*writer).name() << "*********"; // Do the actual writing try { writer->SetOutputLocation(infoIter->m_Path); writer->Write(); } catch(const std::exception& e) { errMsg += std::string("Exception occurred when writing to ") + infoIter->m_Path + ":\n" + e.what() + "\n"; } mitk::ProgressBar::GetInstance()->Progress(2); --filesToWrite; } if (!errMsg.empty()) { MITK_ERROR << errMsg; } mitk::ProgressBar::GetInstance()->Progress(2*filesToWrite); return errMsg; } // This method can be removed after the deprecated LoadDataNode() method was removed void IOUtil::Impl::SetDefaultDataNodeProperties(DataNode* node, const std::string& filePath) { // path mitk::StringProperty::Pointer pathProp = mitk::StringProperty::New( itksys::SystemTools::GetFilenamePath(filePath) ); node->SetProperty(StringProperty::PATH, pathProp); // name already defined? mitk::StringProperty::Pointer nameProp = dynamic_cast(node->GetProperty("name")); if(nameProp.IsNull() || (strcmp(nameProp->GetValue(),"No Name!")==0)) { // name already defined in BaseData mitk::StringProperty::Pointer baseDataNameProp = dynamic_cast(node->GetData()->GetProperty("name").GetPointer() ); if(baseDataNameProp.IsNull() || (strcmp(baseDataNameProp->GetValue(),"No Name!")==0)) { // name neither defined in node, nor in BaseData -> name = filename nameProp = mitk::StringProperty::New( itksys::SystemTools::GetFilenameWithoutExtension(filePath)); node->SetProperty("name", nameProp); } else { // name defined in BaseData! nameProp = mitk::StringProperty::New(baseDataNameProp->GetValue()); node->SetProperty("name", nameProp); } } // visibility if(!node->GetProperty("visible")) { node->SetVisibility(true); } } -IOUtil::SaveInfo::SaveInfo(const BaseData* baseData) - : m_BaseData(baseData) - , m_WriterSelector(baseData, std::string()) - , m_Cancel(false) -{ -} - IOUtil::SaveInfo::SaveInfo(const BaseData* baseData, const MimeType& mimeType, const std::string& path) : m_BaseData(baseData) - , m_MimeType(mimeType) - , m_WriterSelector(baseData, mimeType.IsValid() ? mimeType.GetName() : std::string()) + , m_WriterSelector(baseData, mimeType.GetName(), path) + , m_MimeType(mimeType.IsValid() ? mimeType // use the original mime-type + : (m_WriterSelector.IsEmpty() ? mimeType // no writer found, use the original invalid mime-type + : m_WriterSelector.GetDefault().GetMimeType() // use the found default mime-type + ) + ) , m_Path(path) , m_Cancel(false) { } bool IOUtil::SaveInfo::operator<(const IOUtil::SaveInfo& other) const { int r = strcmp(m_BaseData->GetNameOfClass(), other.m_BaseData->GetNameOfClass()); if (r == 0) { return m_WriterSelector.GetSelected().GetMimeType() < other.m_WriterSelector.GetSelected().GetMimeType(); } return r < 0; } IOUtil::LoadInfo::LoadInfo(const std::string& path) : m_Path(path) , m_ReaderSelector(path) , m_Cancel(false) { } } diff --git a/Core/Code/IO/mitkIOUtil.h b/Core/Code/IO/mitkIOUtil.h index 4368c0d400..6c6c9c75c4 100644 --- a/Core/Code/IO/mitkIOUtil.h +++ b/Core/Code/IO/mitkIOUtil.h @@ -1,451 +1,450 @@ /*=================================================================== 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 #include #include #include #include namespace mitk { /** * \ingroup IO * * \brief A utility class to load and save data from/to the local file system. * * 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 Load(). * * \see QmitkIOUtil */ class MITK_CORE_EXPORT IOUtil { public: struct MITK_CORE_EXPORT LoadInfo { LoadInfo(const std::string& path); std::string m_Path; std::vector m_Output; FileReaderSelector m_ReaderSelector; bool m_Cancel; }; struct MITK_CORE_EXPORT SaveInfo { - SaveInfo(const BaseData* baseData); SaveInfo(const BaseData* baseData, const MimeType& mimeType, const std::string& path); bool operator<(const SaveInfo& other) const; /// The BaseData object to save. const BaseData* m_BaseData; - /// The selected mime-type, used to restrict results from FileWriterSelector. - MimeType m_MimeType; /// Contains a set of IFileWriter objects. FileWriterSelector m_WriterSelector; + /// The selected mime-type, used to restrict results from FileWriterSelector. + MimeType m_MimeType; /// The path to write the BaseData object to. std::string m_Path; /// Flag indicating if sub-sequent save operations are to be canceled. bool m_Cancel; }; /** * 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 char 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()); /** * @brief Load a file into the given DataStorage. * * This method calls Load(const std::vector&, DataStorage&) with a * one-element vector. * * @param path The absolute file name including the file extension. * @param storage A DataStorage object to which the loaded data will be added. * @return The set of added DataNode objects. * @throws mitk::Exception if \c path could not be loaded. * * @sa Load(const std::vector&, DataStorage&) */ static DataStorage::SetOfObjects::Pointer Load(const std::string& path, DataStorage& storage); static DataStorage::SetOfObjects::Pointer Load(const std::string& path, const IFileReader::Options& options, DataStorage& storage); static std::vector Load(const std::string& path); static std::vector Load(const std::string& path, const IFileReader::Options& options); /** * @brief Loads a list of file paths into the given DataStorage. * * If an entry in \c paths cannot be loaded, this method will continue to load * the remaining entries into \c storage and throw an exception afterwards. * * @param paths A list of absolute file names including the file extension. * @param storage A DataStorage object to which the loaded data will be added. * @return The set of added DataNode objects. * @throws mitk::Exception if an entry in \c paths could not be loaded. */ static DataStorage::SetOfObjects::Pointer Load(const std::vector& paths, DataStorage& storage); static std::vector Load(const std::vector& paths); /** * Load 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. * * @deprecatedSince{2014_03} Use Load() instead */ DEPRECATED(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) * * @deprecatedSince{2014_03} Use Load() instead */ DEPRECATED(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. * * @deprecatedSince{2014_03} Use Load() or FileReaderRegistry::Read() instead. */ DEPRECATED(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. * * @deprecatedSince{2014_03} Use Load() instead. */ DEPRECATED(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 Save a mitk::BaseData instance. * @param data The data to save. * @param path The path to the image including file name and and optional file extension. * If no extension is set, the default extension and mime-type for the * BaseData type of \c data is used. * @throws mitk::Exception if no writer for \c data is available or the writer * is not able to write the image. */ static void Save(const mitk::BaseData* data, const std::string& path); /** * @brief Save a mitk::BaseData instance. * @param data The data to save. * @param path The path to the image including file name and an optional file extension. * If no extension is set, the default extension and mime-type for the * BaseData type of \c data is used. * @param options The IFileWriter options to use for the selected writer. * @throws mitk::Exception if no writer for \c data is available or the writer * is not able to write the image. */ static void Save(const mitk::BaseData* data, const std::string& path, const IFileWriter::Options& options); /** * @brief Save a mitk::BaseData instance. * @param data The data to save. * @param mimeType The mime-type to use for writing \c data. * @param path The path to the image including file name and an optional file extension. * @param addExtension If \c true, an extension according to the given \c mimeType * is added to \c path if it does not contain one. If \c path already contains * a file name extension, it is not checked for compatibility with \c mimeType. * * @throws mitk::Exception if no writer for the combination of \c data and \c mimeType is * available or the writer is not able to write the image. */ static void Save(const mitk::BaseData* data, const std::string& mimeType, const std::string& path, bool addExtension = true); /** * @brief Save a mitk::BaseData instance. * @param data The data to save. * @param mimeType The mime-type to use for writing \c data. * @param path The path to the image including file name and an optional file extension. * @param options Configuration data for the used IFileWriter instance. * @param addExtension If \c true, an extension according to the given \c mimeType * is added to \c path if it does not contain one. If \c path already contains * a file name extension, it is not checked for compatibility with \c mimeType. * * @throws mitk::Exception if no writer for the combination of \c data and \c mimeType is * available or the writer is not able to write the image. */ static void Save(const mitk::BaseData* data, const std::string& mimeType, const std::string& path, const mitk::IFileWriter::Options& options, bool addExtension = true); /** * @brief Use SaveInfo objects to save BaseData instances. * * This is a low-level method for directly working with SaveInfo objects. Usually, * the Save() methods taking a BaseData object as an argument are more appropriate. * * @param saveInfos A list of SaveInfo objects for saving contained BaseData objects. * * @see Save(const mitk::BaseData*, const std::string&) */ static void Save(std::vector& saveInfos); /** * @brief SaveImage Convenience method to save an arbitrary mitkImage. * @param path The path to the image including file name and file extension. * If no 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. * * @deprecatedSince{2014_03} Use Save() instead. */ DEPRECATED(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 no extention is set, the default extension 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. * * @deprecatedSince{2014_03} Use Save() instead. */ DEPRECATED(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 no extention is set, the default extension 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. * * @deprecatedSince{2014_03} Use Save() instead. */ DEPRECATED(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. * If no extention is set, the default extension 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. * * @deprecatedSince{2014_03} Use Save() instead. */ DEPRECATED(static bool SavePointSet(mitk::PointSet::Pointer pointset, const std::string& path)); /** @deprecatedSince{2014_03} Use GetDefaultWriteExtension() instead */ DEPRECATED(static const std::string DEFAULTIMAGEEXTENSION); /** @deprecatedSince{2014_03} Use GetDefaultWriteExtension() instead */ DEPRECATED(static const std::string DEFAULTSURFACEEXTENSION); /** @deprecatedSince{2014_03} Use GetDefaultWriteExtension() instead */ DEPRECATED(static const std::string DEFAULTPOINTSETEXTENSION); protected: struct ReaderOptionsFunctorBase { virtual bool operator()(LoadInfo& loadInfo) = 0; }; struct WriterOptionsFunctorBase { virtual bool operator()(SaveInfo& saveInfo) = 0; }; static std::string Load(std::vector& loadInfos, DataStorage::SetOfObjects* nodeResult, DataStorage* ds, ReaderOptionsFunctorBase* optionsCallback); static std::string Save(const BaseData* data, const std::string& mimeType, const std::string& path, WriterOptionsFunctorBase* optionsCallback, bool addExtension); static std::string Save(std::vector& saveInfos, WriterOptionsFunctorBase* optionsCallback); private: struct Impl; }; } #endif // MITKIOUTIL_H diff --git a/Core/Code/Internal/mitkLegacyFileReaderService.cpp b/Core/Code/Internal/mitkLegacyFileReaderService.cpp index e8453fdf89..4077c4c71d 100644 --- a/Core/Code/Internal/mitkLegacyFileReaderService.cpp +++ b/Core/Code/Internal/mitkLegacyFileReaderService.cpp @@ -1,125 +1,125 @@ /*=================================================================== 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 "mitkLegacyFileReaderService.h" #include #include #include #include mitk::LegacyFileReaderService::LegacyFileReaderService(const mitk::LegacyFileReaderService& other) : mitk::AbstractFileReader(other) { } mitk::LegacyFileReaderService::LegacyFileReaderService(const std::vector& extensions, const std::string& category) : AbstractFileReader() { - this->SetMimeTypePrefix("application/vnd.mitk.legacy.reader."); + this->SetMimeTypePrefix("application/vnd.mitk.legacy."); CustomMimeType customMimeType; customMimeType.SetCategory(category); for(std::vector::const_iterator iter = extensions.begin(), endIter = extensions.end(); iter != endIter; ++iter) { std::string extension = *iter; if (!extension.empty() && extension[0] == '.') { extension.assign(extension.begin()+1, extension.end()); } customMimeType.AddExtension(extension); } this->SetDescription(category); this->SetMimeType(customMimeType); m_ServiceReg = this->RegisterService(); } mitk::LegacyFileReaderService::~LegacyFileReaderService() { } ////////////////////// Reading ///////////////////////// std::vector > mitk::LegacyFileReaderService::Read() { std::vector result; std::list possibleIOAdapter; std::list allobjects = itk::ObjectFactoryBase::CreateAllInstance("mitkIOAdapter"); for( std::list::iterator i = allobjects.begin(); i != allobjects.end(); ++i) { IOAdapterBase* io = dynamic_cast(i->GetPointer()); if(io) { possibleIOAdapter.push_back(io); } else { MITK_ERROR << "Error BaseDataIO factory did not return an IOAdapterBase: " << (*i)->GetNameOfClass() << std::endl; } } const std::string path = this->GetLocalFileName(); for( std::list::iterator k = possibleIOAdapter.begin(); k != possibleIOAdapter.end(); ++k ) { bool canReadFile = (*k)->CanReadFile(path, "", ""); // they could read the file if( canReadFile ) { BaseProcess::Pointer ioObject = (*k)->CreateIOProcessObject(path, "", ""); ioObject->Update(); int numberOfContents = static_cast(ioObject->GetNumberOfOutputs()); if (numberOfContents > 0) { BaseData::Pointer baseData; for(int i=0; i(ioObject->GetOutputs()[i].GetPointer()); if (baseData) // this is what's wanted, right? { result.push_back( baseData ); } } } break; } } if (result.empty()) { mitkThrow() << "Could not read file '" << path << "'"; } return result; } mitk::LegacyFileReaderService* mitk::LegacyFileReaderService::Clone() const { return new LegacyFileReaderService(*this); } diff --git a/Core/Code/Internal/mitkLegacyFileWriterService.cpp b/Core/Code/Internal/mitkLegacyFileWriterService.cpp index 09d59d8440..099b429ed9 100644 --- a/Core/Code/Internal/mitkLegacyFileWriterService.cpp +++ b/Core/Code/Internal/mitkLegacyFileWriterService.cpp @@ -1,86 +1,85 @@ /*=================================================================== 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 "mitkLegacyFileWriterService.h" #include #include mitk::LegacyFileWriterService::LegacyFileWriterService(mitk::FileWriter::Pointer legacyWriter, const std::string& description) : AbstractFileWriter(legacyWriter->GetSupportedBaseData()) , m_LegacyWriter(legacyWriter) { - this->SetMimeTypePrefix("application/vnd.mitk.legacy.writer."); + this->SetMimeTypePrefix("application/vnd.mitk.legacy."); this->SetDescription(description); - std::vector extensions = legacyWriter->GetPossibleFileExtensions(); - CustomMimeType customMimeType; + std::vector extensions = legacyWriter->GetPossibleFileExtensions(); for(std::vector::iterator ext = extensions.begin(); ext != extensions.end(); ext++) { if (ext->empty()) continue; std::string extension = *ext; if (extension.size() > 1 && extension[0] == '*') { // remove "*" extension = extension.substr(1); } if (extension.size() > 1 && extension[0] == '.') { // remove "." extension = extension.substr(1); } std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); customMimeType.AddExtension(extension); } this->SetMimeType(customMimeType); m_ServiceRegistration = RegisterService(); } mitk::LegacyFileWriterService::~LegacyFileWriterService() { } ////////////////////// Writing ///////////////////////// void mitk::LegacyFileWriterService::Write() { if (m_LegacyWriter.IsNull()) mitkThrow() << "LegacyFileWriterService was incorrectly initialized: Has no LegacyFileWriter."; LocalFile localFile(this); m_LegacyWriter->SetFileName(localFile.GetFileName().c_str()); m_LegacyWriter->SetInput(const_cast(this->GetInput())); m_LegacyWriter->Write(); } mitk::IFileWriter::ConfidenceLevel mitk::LegacyFileWriterService::GetConfidenceLevel() const { if (mitk::AbstractFileWriter::GetConfidenceLevel() == Unsupported) return Unsupported; DataNode::Pointer node = DataNode::New(); node->SetData(const_cast(this->GetInput())); return m_LegacyWriter->CanWriteDataType(node) ? Supported : Unsupported; } mitk::LegacyFileWriterService* mitk::LegacyFileWriterService::Clone() const { return new LegacyFileWriterService(*this); } diff --git a/Core/Code/Internal/mitkMimeTypeProvider.cpp b/Core/Code/Internal/mitkMimeTypeProvider.cpp index 49d4cbd11b..0ca97fe3d9 100644 --- a/Core/Code/Internal/mitkMimeTypeProvider.cpp +++ b/Core/Code/Internal/mitkMimeTypeProvider.cpp @@ -1,193 +1,198 @@ /*=================================================================== 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 "mitkMimeTypeProvider.h" #include "mitkLogMacros.h" #include #include #include #ifdef _MSC_VER #pragma warning(disable:4503) // decorated name length exceeded, name was truncated #pragma warning(disable:4355) #endif namespace mitk { MimeTypeProvider::MimeTypeProvider() : m_Tracker(NULL) { } +MimeTypeProvider::~MimeTypeProvider() +{ + delete m_Tracker; +} + void MimeTypeProvider::Start() { if (m_Tracker == NULL) { m_Tracker = new us::ServiceTracker(us::GetModuleContext(), this); } m_Tracker->Open(); } void MimeTypeProvider::Stop() { m_Tracker->Close(); } std::vector MimeTypeProvider::GetMimeTypes() const { std::vector result; for (std::map::const_iterator iter = m_NameToMimeType.begin(), end = m_NameToMimeType.end(); iter != end; ++iter) { result.push_back(iter->second); } return result; } std::vector MimeTypeProvider::GetMimeTypesForFile(const std::string& filePath) const { // For now, just use the file extension to look-up the registered mime-types. std::string extension = itksys::SystemTools::GetFilenameExtension(filePath); if (!extension.empty()) { extension = extension.substr(1, extension.size()-1); } return this->GetMimeTypesForExtension(extension); } std::vector MimeTypeProvider::GetMimeTypesForExtension(const std::string& extension) const { std::vector result; for (std::map::const_iterator iter = m_NameToMimeType.begin(), iterEnd = m_NameToMimeType.end(); iter != iterEnd; ++iter) { const std::vector extensions = iter->second.GetExtensions(); if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end()) { result.push_back(iter->second); } } std::sort(result.begin(), result.end()); std::reverse(result.begin(), result.end()); return result; } std::vector MimeTypeProvider::GetMimeTypesForCategory(const std::string& category) const { std::vector result; for (std::map::const_iterator iter = m_NameToMimeType.begin(), end = m_NameToMimeType.end(); iter != end; ++iter) { if (iter->second.GetCategory() == category) { result.push_back(iter->second); } } return result; } MimeType MimeTypeProvider::GetMimeTypeForName(const std::string& name) const { std::map::const_iterator iter = m_NameToMimeType.find(name); if (iter != m_NameToMimeType.end()) return iter->second; return MimeType(); } std::vector MimeTypeProvider::GetCategories() const { std::vector result; for (std::map::const_iterator iter = m_NameToMimeType.begin(), end = m_NameToMimeType.end(); iter != end; ++iter) { std::string category = iter->second.GetCategory(); if (!category.empty()) { result.push_back(category); } } std::sort(result.begin(), result.end()); result.erase(std::unique(result.begin(), result.end()), result.end()); return result; } MimeTypeProvider::TrackedType MimeTypeProvider::AddingService(const ServiceReferenceType& reference) { MimeType result = this->GetMimeType(reference); if (result.IsValid()) { std::string name = result.GetName(); m_NameToMimeTypes[name].insert(result); // get the highest ranked mime-type m_NameToMimeType[name] = *(m_NameToMimeTypes[name].rbegin()); } return result; } void MimeTypeProvider::ModifiedService(const ServiceReferenceType& /*reference*/, TrackedType /*mimetype*/) { // should we track changes in the ranking property? } void MimeTypeProvider::RemovedService(const ServiceReferenceType& /*reference*/, TrackedType mimeType) { std::string name = mimeType.GetName(); std::set& mimeTypes = m_NameToMimeTypes[name]; mimeTypes.erase(mimeType); if (mimeTypes.empty()) { m_NameToMimeTypes.erase(name); m_NameToMimeType.erase(name); } else { // get the highest ranked mime-type m_NameToMimeType[name] = *(mimeTypes.rbegin()); } } MimeType MimeTypeProvider::GetMimeType(const ServiceReferenceType& reference) const { MimeType result; if (!reference) return result; CustomMimeType* mimeType = us::GetModuleContext()->GetService(reference); if (mimeType != NULL) { try { int rank = 0; us::Any rankProp = reference.GetProperty(us::ServiceConstants::SERVICE_RANKING()); if (!rankProp.Empty()) { rank = us::any_cast(rankProp); } long id = us::any_cast(reference.GetProperty(us::ServiceConstants::SERVICE_ID())); result = MimeType(*mimeType, rank, id); } catch (const us::BadAnyCastException& e) { MITK_WARN << "Unexpected exception: " << e.what(); } us::GetModuleContext()->UngetService(reference); } return result; } } diff --git a/Core/Code/Internal/mitkMimeTypeProvider.h b/Core/Code/Internal/mitkMimeTypeProvider.h index 357b5cf8a8..59d1152e08 100644 --- a/Core/Code/Internal/mitkMimeTypeProvider.h +++ b/Core/Code/Internal/mitkMimeTypeProvider.h @@ -1,85 +1,86 @@ /*=================================================================== 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 MITKMIMETYPEPROVIDER_H #define MITKMIMETYPEPROVIDER_H #include "mitkIMimeTypeProvider.h" #include "mitkCustomMimeType.h" #include "usServiceTracker.h" #include "usServiceTrackerCustomizer.h" #include namespace mitk { struct MimeTypeTrackerTypeTraits : public us::TrackedTypeTraitsBase { typedef MimeType TrackedType; static bool IsValid(const TrackedType& t) { return t.IsValid(); } static TrackedType DefaultValue() { return TrackedType(); } static void Dispose(TrackedType& /*t*/) { } }; class MimeTypeProvider : public IMimeTypeProvider, private us::ServiceTrackerCustomizer { public: MimeTypeProvider(); + ~MimeTypeProvider(); void Start(); void Stop(); virtual std::vector GetMimeTypes() const; virtual std::vector GetMimeTypesForFile(const std::string& filePath) const; virtual std::vector GetMimeTypesForExtension(const std::string& extension) const; virtual std::vector GetMimeTypesForCategory(const std::string& category) const; virtual MimeType GetMimeTypeForName(const std::string& name) const; virtual std::vector GetCategories() const; private: virtual TrackedType AddingService(const ServiceReferenceType& reference); virtual void ModifiedService(const ServiceReferenceType& reference, TrackedType service); virtual void RemovedService(const ServiceReferenceType& reference, TrackedType service); MimeType GetMimeType(const ServiceReferenceType& reference) const; us::ServiceTracker* m_Tracker; typedef std::map > MapType; MapType m_NameToMimeTypes; std::map m_NameToMimeType; }; } #endif // MITKMIMETYPEPROVIDER_H diff --git a/Core/Code/Testing/files.cmake b/Core/Code/Testing/files.cmake index d330fea092..939ba93d9b 100644 --- a/Core/Code/Testing/files.cmake +++ b/Core/Code/Testing/files.cmake @@ -1,199 +1,199 @@ # tests with no extra command line parameter set(MODULE_TESTS # IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code. # # Example: #mitkMyTest #this test is commented out because of bug 12345 # # It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that # no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and # mark it as critical. ################## DISABLED TESTS ################################################# #mitkAbstractTransformGeometryTest.cpp #seems as tested class mitkExternAbstractTransformGeometry doesnt exist any more #mitkStateMachineContainerTest.cpp #rewrite test, indirect since no longer exported Bug 14529 #mitkRegistrationBaseTest.cpp #tested class mitkRegistrationBase doesn't exist any more #mitkSegmentationInterpolationTest.cpp #file doesn't exist! #mitkPipelineSmartPointerCorrectnessTest.cpp #file doesn't exist! #mitkITKThreadingTest.cpp #test outdated because itk::Semaphore was removed from ITK #mitkAbstractTransformPlaneGeometryTest.cpp #mitkVtkAbstractTransformPlaneGeometry doesn't exist any more #mitkTestUtilSharedLibrary.cpp #Linker problem with this test... #mitkTextOverlay2DSymbolsRenderingTest.cpp #Implementation of the tested feature is not finished yet. Ask Christoph or see bug 15104 for details. ################# RUNNING TESTS ################################################### mitkAccessByItkTest.cpp mitkCoreObjectFactoryTest.cpp mitkDataNodeTest.cpp mitkMaterialTest.cpp mitkActionTest.cpp mitkDispatcherTest.cpp mitkEnumerationPropertyTest.cpp mitkEventTest.cpp mitkFileReaderRegistryTest.cpp #mitkFileWriterRegistryTest.cpp mitkFocusManagerTest.cpp mitkGenericPropertyTest.cpp mitkGeometry3DTest.cpp mitkGeometry3DEqualTest.cpp mitkGeometryDataToSurfaceFilterTest.cpp mitkGlobalInteractionTest.cpp mitkImageCastTest.cpp mitkImageEqualTest.cpp mitkImageDataItemTest.cpp mitkImageGeneratorTest.cpp mitkIOUtilTest.cpp mitkBaseDataTest.cpp mitkImportItkImageTest.cpp mitkGrabItkImageMemoryTest.cpp mitkInstantiateAccessFunctionTest.cpp mitkInteractorTest.cpp mitkLevelWindowTest.cpp mitkMessageTest.cpp mitkPixelTypeTest.cpp mitkPlaneGeometryTest.cpp mitkPointSetTest.cpp mitkPointSetEqualTest.cpp mitkPointSetFileIOTest.cpp mitkPointSetOnEmptyTest.cpp mitkPointSetWriterTest.cpp mitkPointSetReaderTest.cpp mitkPointSetInteractorTest.cpp mitkPointSetPointOperationsTest.cpp mitkProgressBarTest.cpp mitkPropertyTest.cpp mitkPropertyListTest.cpp mitkSlicedGeometry3DTest.cpp mitkSliceNavigationControllerTest.cpp mitkStateMachineTest.cpp mitkStateTest.cpp mitkSurfaceTest.cpp mitkSurfaceEqualTest.cpp mitkSurfaceToSurfaceFilterTest.cpp mitkTimeGeometryTest.cpp mitkProportionalTimeGeometryTest.cpp mitkTransitionTest.cpp mitkUndoControllerTest.cpp mitkVtkWidgetRenderingTest.cpp mitkVerboseLimitedLinearUndoTest.cpp mitkWeakPointerTest.cpp mitkTransferFunctionTest.cpp mitkStepperTest.cpp mitkRenderingManagerTest.cpp vtkMitkThickSlicesFilterTest.cpp mitkNodePredicateSourceTest.cpp mitkVectorTest.cpp mitkClippedSurfaceBoundsCalculatorTest.cpp mitkExceptionTest.cpp mitkExtractSliceFilterTest.cpp mitkLogTest.cpp mitkImageDimensionConverterTest.cpp mitkLoggingAdapterTest.cpp mitkUIDGeneratorTest.cpp mitkShaderRepositoryTest.cpp mitkPlanePositionManagerTest.cpp mitkAffineTransformBaseTest.cpp mitkPropertyAliasesTest.cpp mitkPropertyDescriptionsTest.cpp mitkPropertyExtensionsTest.cpp mitkPropertyFiltersTest.cpp mitkTinyXMLTest.cpp mitkRawImageFileReaderTest.cpp mitkInteractionEventTest.cpp mitkLookupTableTest.cpp - #mitkSTLFileReaderTest.cpp + mitkSTLFileReaderTest.cpp mitkPointTypeConversionTest.cpp mitkVectorTypeConversionTest.cpp mitkMatrixTypeConversionTest.cpp mitkArrayTypeConversionTest.cpp mitkSurfaceToImageFilterTest.cpp mitkBaseGeometryTest.cpp mitkImageToSurfaceFilterTest.cpp mitkEqualTest.cpp mitkLineTest.cpp ) if(MITK_ENABLE_RENDERING_TESTING) #since mitkInteractionTestHelper is currently creating a vtkRenderWindow set(MODULE_TESTS ${MODULE_TESTS} mitkPointSetDataInteractorTest.cpp ) endif() # test with image filename as an extra command line parameter set(MODULE_IMAGE_TESTS mitkImageTimeSelectorTest.cpp #only runs on images mitkImageAccessorTest.cpp #only runs on images ) set(MODULE_SURFACE_TESTS mitkSurfaceVtkWriterTest.cpp #only runs on surfaces ) # list of images for which the tests are run set(MODULE_TESTIMAGES US4DCyl.nrrd Pic3D.nrrd Pic2DplusT.nrrd BallBinary30x30x30.nrrd Png2D-bw.png ) set(MODULE_TESTSURFACES binary.stl ball.stl ) set(MODULE_CUSTOM_TESTS mitkDataStorageTest.cpp mitkDicomSeriesReaderTest.cpp mitkDICOMLocaleTest.cpp mitkEventMapperTest.cpp mitkEventConfigTest.cpp mitkNodeDependentPointSetInteractorTest.cpp mitkStateMachineFactoryTest.cpp mitkPointSetLocaleTest.cpp mitkImageTest.cpp - #mitkImageWriterTest.cpp + mitkImageWriterTest.cpp mitkImageVtkMapper2DTest.cpp mitkImageVtkMapper2DLevelWindowTest.cpp mitkImageVtkMapper2DOpacityTest.cpp mitkImageVtkMapper2DResliceInterpolationPropertyTest.cpp mitkImageVtkMapper2DColorTest.cpp mitkImageVtkMapper2DSwivelTest.cpp mitkImageVtkMapper2DTransferFunctionTest.cpp mitkImageVtkMapper2DOpacityTransferFunctionTest.cpp mitkImageVtkMapper2DLookupTableTest.cpp mitkSurfaceVtkMapper3DTest mitkSurfaceVtkMapper3DTexturedSphereTest.cpp mitkSurfaceGLMapper2DColorTest.cpp mitkSurfaceGLMapper2DOpacityTest.cpp mitkVolumeCalculatorTest.cpp mitkLevelWindowManagerTest.cpp mitkPointSetVtkMapper2DTest.cpp mitkPointSetVtkMapper2DImageTest.cpp mitkPointSetVtkMapper2DGlyphTypeTest.cpp mitkPointSetVtkMapper2DTransformedPointsTest.cpp mitkVTKRenderWindowSizeTest.cpp mitkMultiComponentImageDataComparisonFilterTest.cpp mitkImageToItkTest.cpp mitkImageSliceSelectorTest.cpp mitkSurfaceDepthPeelingTest.cpp mitkSurfaceDepthSortingTest.cpp ) set(MODULE_RESOURCE_FILES Interactions/AddAndRemovePoints.xml Interactions/globalConfig.xml Interactions/StatemachineTest.xml Interactions/StatemachineConfigTest.xml ) # Embed the resources set(testdriver_resources ) usFunctionEmbedResources(testdriver_resources EXECUTABLE_NAME ${MODULE_NAME}TestDriver ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Resources FILES ${MODULE_RESOURCE_FILES} ) set(TEST_CPP_FILES ${testdriver_init_file} ${testdriver_resources}) diff --git a/Core/Code/Testing/mitkImageWriterTest.cpp b/Core/Code/Testing/mitkImageWriterTest.cpp index 979bf75805..5df68f0b2b 100644 --- a/Core/Code/Testing/mitkImageWriterTest.cpp +++ b/Core/Code/Testing/mitkImageWriterTest.cpp @@ -1,256 +1,259 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include "mitkException.h" #include #include "mitkIOUtil.h" -#include "mitkFileWriterRegistry.h" #include "itksys/SystemTools.hxx" #include #include #ifdef WIN32 #include "process.h" #else #include #endif std::string AppendExtension(const std::string &filename, const char *extension) { std::string new_filename = filename; new_filename += extension; return new_filename; } bool CompareImageMetaData( mitk::Image::Pointer image, mitk::Image::Pointer reference, bool checkPixelType = true ) { // switch to AreIdentical() methods as soon as Bug 11925 (Basic comparison operators) is fixed if( image->GetDimension() != reference->GetDimension() ) { MITK_ERROR << "The image dimension differs: IN (" << image->GetDimension() << ") REF(" << reference->GetDimension() << ")"; return false; } // pixel type if( checkPixelType && ( image->GetPixelType() != reference->GetPixelType() && image->GetPixelType().GetBitsPerComponent() != reference->GetPixelType().GetBitsPerComponent() ) ) { MITK_ERROR << "Pixeltype differs ( image=" << image->GetPixelType().GetPixelTypeAsString() << "[" << image->GetPixelType().GetBitsPerComponent() << "]" << " reference=" << reference->GetPixelType().GetPixelTypeAsString() << "[" << reference->GetPixelType().GetBitsPerComponent() << "]" << " )"; return false; } return true; } /* Test writing picture formats like *.bmp, *.png, *.tiff or *.jpg NOTE: Saving as picture format must ignore PixelType comparison - not all bits per components are supported (see specification of the format) */ void TestPictureWriting(mitk::Image* image, const std::string& filename, const std::string& extension) { const std::string fullFileName = AppendExtension(filename, extension.c_str()); mitk::Image::Pointer singleSliceImage = NULL; if( image->GetDimension() == 3 ) { mitk::ExtractSliceFilter::Pointer extractFilter = mitk::ExtractSliceFilter::New(); extractFilter->SetInput( image ); extractFilter->SetWorldGeometry( image->GetSlicedGeometry()->GetPlaneGeometry(0) ); extractFilter->Update(); singleSliceImage = extractFilter->GetOutput(); // test 3D writing in format supporting only 2D - mitk::FileWriterRegistry::Write(image, fullFileName); + mitk::IOUtil::Save(image, fullFileName); // test images unsigned int foundImagesCount = 0; //if the image only contains one sinlge slice the itkImageSeriesWriter won't add a number like filename.XX.extension if(image->GetDimension(2) == 1) { std::stringstream series_filenames; - series_filenames << filename << extension; - mitk::Image::Pointer compareImage = mitk::IOUtil::LoadImage( series_filenames.str() ); - if( compareImage.IsNotNull() ) - { - foundImagesCount++; - MITK_TEST_CONDITION(CompareImageMetaData( singleSliceImage, compareImage, false ), "Image meta data unchanged after writing and loading again. "); //ignore bits per component - } - remove( series_filenames.str().c_str() ); + series_filenames << filename << extension; + mitk::Image::Pointer compareImage = mitk::IOUtil::LoadImage( series_filenames.str() ); + if( compareImage.IsNotNull() ) + { + foundImagesCount++; + MITK_TEST_CONDITION(CompareImageMetaData( singleSliceImage, compareImage, false ), "Image meta data unchanged after writing and loading again. "); //ignore bits per component + } + remove( series_filenames.str().c_str() ); } else //test the whole slice stack { for( unsigned int i=0; i< image->GetDimension(2); i++) { std::stringstream series_filenames; series_filenames << filename << "." << i+1 << extension; mitk::Image::Pointer compareImage = mitk::IOUtil::LoadImage( series_filenames.str() ); if( compareImage.IsNotNull() ) { foundImagesCount++; MITK_TEST_CONDITION(CompareImageMetaData( singleSliceImage, compareImage, false ), "Image meta data unchanged after writing and loading again. "); //ignore bits per component } remove( series_filenames.str().c_str() ); } } MITK_TEST_CONDITION( foundImagesCount == image->GetDimension(2), "All 2D-Slices of a 3D image were stored correctly."); } else if( image->GetDimension() == 2 ) { singleSliceImage = image; } // test 2D writing if( singleSliceImage.IsNotNull() ) { try { - mitk::FileWriterRegistry::Write(singleSliceImage, fullFileName); + mitk::IOUtil::Save(singleSliceImage, fullFileName); mitk::Image::Pointer compareImage = mitk::IOUtil::LoadImage(fullFileName.c_str()); MITK_TEST_CONDITION_REQUIRED( compareImage.IsNotNull(), "Image stored was succesfully loaded again"); MITK_TEST_CONDITION_REQUIRED( CompareImageMetaData(singleSliceImage, compareImage, false ), "Image meta data unchanged after writing and loading again. ");//ignore bits per component - remove(AppendExtension(filename, extension.c_str()).c_str()); + remove(fullFileName.c_str()); } catch(itk::ExceptionObject &e) { MITK_TEST_FAILED_MSG(<< "Exception during file writing for ." << extension << ": " << e.what() ); } } } /** * test for "ImageWriter". * * argc and argv are the command line parameters which were passed to * the ADD_TEST command in the CMakeLists.txt file. For the automatic * tests, argv is either empty for the simple tests or contains the filename * of a test image for the image tests (see CMakeLists.txt). */ int mitkImageWriterTest(int argc , char* argv[]) { // always start with this! MITK_TEST_BEGIN("ImageWriter") // write your own tests here and use the macros from mitkTestingMacros.h !!! // do not write to std::cout and do not return from this function yourself! // load image MITK_TEST_CONDITION_REQUIRED(argc > 1, "File to load has been specified"); mitk::Image::Pointer image = NULL; try { MITK_TEST_OUTPUT(<< "Loading file: " << argv[1]); image = mitk::IOUtil::LoadImage( argv[1] ); } catch (itk::ExceptionObject & ex) { MITK_TEST_FAILED_MSG(<< "Exception during file loading: " << ex.GetDescription()); } MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(),"loaded image not NULL") - mitk::FileWriterRegistry writerRegistry; - - std::ofstream tmpStream; - std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream); - tmpStream.close(); - - // write ITK .mhd image (2D and 3D only) + // write ITK .mhd image (2D and 3D only) if( image->GetDimension() <= 3 ) { + std::ofstream tmpStream; + std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.mhd"); + tmpStream.close(); + + std::string tmpFilePathWithoutExt = tmpFilePath.substr(0, tmpFilePath.size() - 4); + try { - mitk::IFileWriter* writer = writerRegistry.GetWriter(mitk::Image::GetStaticNameOfClass(), ".mhd"); - writer->Write(image, tmpFilePath); + mitk::IOUtil::Save(image, tmpFilePath); mitk::Image::Pointer compareImage = mitk::IOUtil::LoadImage(tmpFilePath); MITK_TEST_CONDITION_REQUIRED( compareImage.IsNotNull(), "Image stored in MHD format was succesfully loaded again! "); - MITK_TEST_CONDITION(itksys::SystemTools::FileExists((tmpFilePath + ".mhd").c_str()), ".mhd file exists") - MITK_TEST_CONDITION(itksys::SystemTools::FileExists((tmpFilePath + ".raw").c_str()) || - itksys::SystemTools::FileExists((tmpFilePath + ".zraw").c_str()), ".raw or .zraw exists") + MITK_TEST_CONDITION(itksys::SystemTools::FileExists((tmpFilePathWithoutExt + ".mhd").c_str()), ".mhd file exists") + MITK_TEST_CONDITION(itksys::SystemTools::FileExists((tmpFilePathWithoutExt + ".raw").c_str()) || + itksys::SystemTools::FileExists((tmpFilePathWithoutExt + ".zraw").c_str()), ".raw or .zraw exists") // delete - remove((tmpFilePath + ".mhd").c_str()); - remove((tmpFilePath + ".raw").c_str()); - remove((tmpFilePath + ".zraw").c_str()); + remove(tmpFilePath.c_str()); + remove((tmpFilePathWithoutExt + ".raw").c_str()); + remove((tmpFilePathWithoutExt + ".zraw").c_str()); } - catch (...) + catch (const std::exception& e) { - MITK_TEST_FAILED_MSG(<< "Exception during .mhd file writing"); + MITK_TEST_FAILED_MSG(<< "Exception during .mhd file writing: " << e.what()); } } //testing more component image writing as nrrd files - try - { - mitk::IFileWriter* writer = writerRegistry.GetWriter(mitk::Image::GetStaticNameOfClass(), ".nrrd"); - writer->Write(image, tmpFilePath); - - std::fstream fin; - mitk::Image::Pointer compareImage = mitk::IOUtil::LoadImage(AppendExtension(tmpFilePath, ".nrrd").c_str()); - MITK_TEST_CONDITION_REQUIRED(compareImage.IsNotNull(), "Image stored in NRRD format was succesfully loaded again"); - fin.close(); - remove(AppendExtension(tmpFilePath, ".nrrd").c_str()); - } - catch(...) + { - MITK_TEST_FAILED_MSG(<< "Exception during .nrrd file writing"); + std::ofstream tmpStream; + std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.nrrd"); + tmpStream.close(); + + try + { + mitk::IOUtil::Save(image, tmpFilePath); + + mitk::Image::Pointer compareImage = mitk::IOUtil::LoadImage(tmpFilePath); + MITK_TEST_CONDITION_REQUIRED(compareImage.IsNotNull(), "Image stored in NRRD format was succesfully loaded again"); + + remove(tmpFilePath.c_str()); + } + catch(...) + { + std::remove(tmpFilePath.c_str()); + MITK_TEST_FAILED_MSG(<< "Exception during .nrrd file writing"); + } } + std::ofstream tmpStream; + std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX"); + tmpStream.close(); + TestPictureWriting(image, tmpFilePath, ".png"); TestPictureWriting(image, tmpFilePath, ".jpg"); TestPictureWriting(image, tmpFilePath, ".tiff"); TestPictureWriting(image, tmpFilePath, ".bmp"); // test for exception handling - std::vector writers = writerRegistry.GetWriters(mitk::Image::GetStaticNameOfClass()); - for (std::vector::const_iterator iter = writers.begin(), - end = writers.end(); iter != end; ++iter) + try { - try - { - (*iter)->Write(image, "/usr/bin"); - MITK_TEST_FAILED_MSG( << "itk::ExceptionObject expected") - } - catch (const itk::ExceptionObject&) { /* this is expected */ } - catch(...) - { - //this means that a wrong exception (i.e. no itk:Exception) has been thrown - MITK_TEST_FAILED_MSG(<< "Wrong exception (i.e. no itk:Exception) caught during write"); - } + mitk::IOUtil::Save(image, "/usr/bin"); + MITK_TEST_FAILED_MSG( << "mitk::Exception expected") + } + catch (const mitk::Exception&) { /* this is expected */ } + catch (...) + { + //this means that a wrong exception (i.e. no itk:Exception) has been thrown + MITK_TEST_FAILED_MSG(<< "Wrong exception (i.e. no itk:Exception) caught during write"); } // always end with this! MITK_TEST_END(); } diff --git a/Core/Code/Testing/mitkSTLFileReaderTest.cpp b/Core/Code/Testing/mitkSTLFileReaderTest.cpp index 7876cf03c6..3190525e42 100644 --- a/Core/Code/Testing/mitkSTLFileReaderTest.cpp +++ b/Core/Code/Testing/mitkSTLFileReaderTest.cpp @@ -1,84 +1,79 @@ /*=================================================================== 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 "mitkImage.h" -#include "mitkSTLFileReader.h" #include "mitkSlicedGeometry3D.h" #include "mitkSurface.h" +#include "mitkIOUtil.h" #include "mitkTestingMacros.h" #include "mitkTestFixture.h" #include #include #include #include class mitkSTLFileReaderTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkSTLFileReaderTestSuite); MITK_TEST(testReadFile); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different test methods. All members are initialized via setUp().*/ std::string m_SurfacePath; public: /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() { m_SurfacePath = GetTestDataFilePath("ball.stl"); } void tearDown() { } -void testReadFile() + void testReadFile() { - //Read STL-Image from file - mitk::STLFileReader::Pointer reader = mitk::STLFileReader::New(); - if (!reader->CanReadFile(m_SurfacePath, "", "")) {CPPUNIT_FAIL("Cannot read test data STL file.");} - reader->SetFileName(m_SurfacePath); - reader->Update(); - mitk::Surface::Pointer surface = reader->GetOutput(); - - //check some basic stuff - CPPUNIT_ASSERT_MESSAGE("Reader output not NULL",surface.IsNotNull()); - CPPUNIT_ASSERT_MESSAGE("IsInitialized()",surface->IsInitialized()); - CPPUNIT_ASSERT_MESSAGE("mitk::Surface::SetVtkPolyData()",(surface->GetVtkPolyData()!=NULL)); - CPPUNIT_ASSERT_MESSAGE("Availability of geometry",(surface->GetGeometry()!=NULL)); - - //use vtk stl reader for reference - vtkSmartPointer myVtkSTLReader = vtkSmartPointer::New(); - myVtkSTLReader->SetFileName( m_SurfacePath.c_str() ); - myVtkSTLReader->Update(); - vtkSmartPointer myVtkPolyData = myVtkSTLReader->GetOutput(); - //vtkPolyData from vtkSTLReader directly - int n = myVtkPolyData->GetNumberOfPoints(); - //vtkPolyData from mitkSTLFileReader - int m = surface->GetVtkPolyData()->GetNumberOfPoints(); - CPPUNIT_ASSERT_MESSAGE("Number of Points in VtkPolyData",(n == m)); - + //Read STL-Image from file + mitk::Surface::Pointer surface = mitk::IOUtil::LoadSurface(m_SurfacePath); + + //check some basic stuff + CPPUNIT_ASSERT_MESSAGE("Reader output not NULL",surface.IsNotNull()); + CPPUNIT_ASSERT_MESSAGE("IsInitialized()",surface->IsInitialized()); + CPPUNIT_ASSERT_MESSAGE("mitk::Surface::SetVtkPolyData()",(surface->GetVtkPolyData()!=NULL)); + CPPUNIT_ASSERT_MESSAGE("Availability of geometry",(surface->GetGeometry()!=NULL)); + + //use vtk stl reader for reference + vtkSmartPointer myVtkSTLReader = vtkSmartPointer::New(); + myVtkSTLReader->SetFileName( m_SurfacePath.c_str() ); + myVtkSTLReader->Update(); + vtkSmartPointer myVtkPolyData = myVtkSTLReader->GetOutput(); + //vtkPolyData from vtkSTLReader directly + int n = myVtkPolyData->GetNumberOfPoints(); + //vtkPolyData from mitkSTLFileReader + int m = surface->GetVtkPolyData()->GetNumberOfPoints(); + CPPUNIT_ASSERT_MESSAGE("Number of Points in VtkPolyData",(n == m)); } }; MITK_TEST_SUITE_REGISTRATION(mitkSTLFileReader)