31 #include <itksys/SystemTools.hxx> 34 #include <vtkPolyData.h> 35 #include <vtkSmartPointer.h> 36 #include <vtkTriangleFilter.h> 43 #ifdef US_PLATFORM_POSIX 44 return std::string(strerror(errno));
48 DWORD dw = GetLastError();
50 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
53 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
58 std::string errMsg((LPCTSTR)lpMsgBuf);
66 #ifdef US_PLATFORM_WINDOWS 72 #define S_IRUSR S_IREAD 73 #define S_IWUSR S_IWRITE 78 #include <sys/types.h> 86 static const char validLetters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
91 static unsigned long long value = 0;
92 int savedErrno = errno;
95 #define ATTEMPTS_MIN (62 * 62 * 62) 99 #if ATTEMPTS_MIN < TMP_MAX 100 const unsigned int attempts = TMP_MAX;
105 const int len = strlen(tmpl);
106 if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen],
"XXXXXX", 6))
113 char *XXXXXX = &tmpl[len - 6 - suffixlen];
116 #ifdef US_PLATFORM_WINDOWS 122 GetSystemTime(&stNow);
123 stNow.wMilliseconds = 500;
124 if (!SystemTimeToFileTime(&stNow, &ftNow))
129 unsigned long long randomTimeBits = ((
static_cast<unsigned long long>(ftNow.dwHighDateTime) << 32) |
130 static_cast<unsigned long long>(ftNow.dwLowDateTime));
131 value = randomTimeBits ^
static_cast<unsigned long long>(GetCurrentThreadId());
136 gettimeofday(&tv,
nullptr);
137 unsigned long long randomTimeBits =
138 ((
static_cast<unsigned long long>(tv.tv_usec) << 32) |
static_cast<unsigned long long>(tv.tv_sec));
139 value = randomTimeBits ^
static_cast<unsigned long long>(getpid());
143 for (
unsigned int count = 0; count < attempts; value += 7777, ++count)
145 unsigned long long v = value;
160 int fd = open(tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
166 else if (errno != EEXIST)
180 static unsigned long long value = 0;
181 int savedErrno = errno;
184 #define ATTEMPTS_MIN (62 * 62 * 62) 188 #if ATTEMPTS_MIN < TMP_MAX 189 const unsigned int attempts = TMP_MAX;
194 const int len = strlen(tmpl);
195 if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen],
"XXXXXX", 6))
202 char *XXXXXX = &tmpl[len - 6 - suffixlen];
205 #ifdef US_PLATFORM_WINDOWS 211 GetSystemTime(&stNow);
212 stNow.wMilliseconds = 500;
213 if (!SystemTimeToFileTime(&stNow, &ftNow))
218 unsigned long long randomTimeBits = ((
static_cast<unsigned long long>(ftNow.dwHighDateTime) << 32) |
219 static_cast<unsigned long long>(ftNow.dwLowDateTime));
220 value = randomTimeBits ^
static_cast<unsigned long long>(GetCurrentThreadId());
225 gettimeofday(&tv,
nullptr);
226 unsigned long long randomTimeBits =
227 ((
static_cast<unsigned long long>(tv.tv_usec) << 32) |
static_cast<unsigned long long>(tv.tv_sec));
228 value = randomTimeBits ^
static_cast<unsigned long long>(getpid());
232 unsigned int count = 0;
233 for (; count < attempts; value += 7777, ++count)
235 unsigned long long v = value;
250 #ifdef US_PLATFORM_WINDOWS 251 int fd = _mkdir(tmpl);
253 int fd = mkdir(tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
260 else if (errno != EEXIST)
280 struct FixedReaderOptionsFunctor :
public ReaderOptionsFunctorBase
283 bool operator()(LoadInfo &loadInfo)
const override 285 IFileReader *reader = loadInfo.m_ReaderSelector.GetSelected().GetReader();
288 reader->SetOptions(m_Options);
297 struct FixedWriterOptionsFunctor :
public WriterOptionsFunctorBase
300 bool operator()(SaveInfo &saveInfo)
const override 302 IFileWriter *writer = saveInfo.m_WriterSelector.GetSelected().GetWriter();
305 writer->SetOptions(m_Options);
314 static BaseData::Pointer LoadBaseDataFromFile(
const std::string &path,
const ReaderOptionsFunctorBase* optionsCallback =
nullptr);
316 static void SetDefaultDataNodeProperties(
mitk::DataNode *node,
const std::string &filePath = std::string());
320 const ReaderOptionsFunctorBase *optionsCallback)
322 std::vector<BaseData::Pointer> baseDataList =
Load(path, optionsCallback);
325 assert(!baseDataList.empty());
326 return baseDataList.front();
329 #ifdef US_PLATFORM_WINDOWS 333 std::size_t index = std::string(path, GetModuleFileName(
nullptr, path, 512)).find_last_of(
'\\');
334 return std::string(path, index);
336 #elif defined(US_PLATFORM_APPLE) 337 #include <mach-o/dyld.h> 341 uint32_t size =
sizeof(path);
342 if (_NSGetExecutablePath(path, &size) == 0)
344 std::size_t index = std::string(path).find_last_of(
'/');
345 std::string strPath = std::string(path, index);
350 return std::string();
354 #include <sys/types.h> 358 std::stringstream ss;
359 ss <<
"/proc/" << getpid() <<
"/exe";
360 char proc[512] = {0};
361 ssize_t ch = readlink(ss.str().c_str(), proc, 512);
363 return std::string();
364 std::size_t index = std::string(proc).find_last_of(
'/');
365 return std::string(proc, index);
371 #ifdef US_PLATFORM_WINDOWS 380 static std::string result;
383 #ifdef US_PLATFORM_WINDOWS 384 char tempPathTestBuffer[1];
386 if (bufferLength == 0)
390 std::vector<char> tempPath(bufferLength);
392 if (bufferLength == 0)
396 result.assign(tempPath.begin(), tempPath.begin() +
static_cast<std::size_t
>(bufferLength));
407 ofstream tmpOutputStream;
409 tmpOutputStream.close();
415 return CreateTemporaryFile(f, std::ios_base::out | std::ios_base::trunc, templateName, path);
419 std::ios_base::openmode mode,
420 const std::string &templateName,
428 path += templateName;
430 std::vector<char> dst_path(path.begin(), path.end());
431 dst_path.push_back(
'\0');
433 std::size_t lastX = path.find_last_of(
'X');
434 std::size_t firstX = path.find_last_not_of(
'X', lastX);
435 int firstNonX = firstX == std::string::npos ? -1 : firstX - 1;
436 while (lastX != std::string::npos && (lastX - firstNonX) < 6)
438 lastX = path.find_last_of(
'X', firstX);
439 firstX = path.find_last_not_of(
'X', lastX);
440 firstNonX = firstX == std::string::npos ? -1 : firstX - 1;
442 std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1;
447 path.assign(dst_path.begin(), dst_path.end() - 1);
448 f.open(path.c_str(), mode | std::ios_base::out | std::ios_base::trunc);
466 std::vector<char> dst_path(path.begin(), path.end());
467 dst_path.push_back(
'\0');
469 std::size_t lastX = path.find_last_of(
'X');
470 std::size_t firstX = path.find_last_not_of(
'X', lastX);
471 int firstNonX = firstX == std::string::npos ? -1 : firstX - 1;
472 while (lastX != std::string::npos && (lastX - firstNonX) < 6)
474 lastX = path.find_last_of(
'X', firstX);
475 firstX = path.find_last_not_of(
'X', lastX);
476 firstNonX = firstX == std::string::npos ? -1 : firstX - 1;
478 std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1;
485 path.assign(dst_path.begin(), dst_path.end() - 1);
491 std::vector<std::string> paths;
492 paths.push_back(path);
493 return Load(paths, storage, optionsCallback);
496 DataStorage::SetOfObjects::Pointer
IOUtil::Load(
const std::string &path,
500 std::vector<LoadInfo> loadInfos;
501 loadInfos.push_back(
LoadInfo(path));
502 DataStorage::SetOfObjects::Pointer nodeResult = DataStorage::SetOfObjects::New();
503 Impl::FixedReaderOptionsFunctor optionsCallback(options);
504 std::string errMsg =
Load(loadInfos, nodeResult, &storage, &optionsCallback);
514 std::vector<std::string> paths;
515 paths.push_back(path);
516 return Load(paths, optionsCallback);
521 std::vector<LoadInfo> loadInfos;
522 loadInfos.push_back(
LoadInfo(path));
523 Impl::FixedReaderOptionsFunctor optionsCallback(options);
524 std::string errMsg =
Load(loadInfos,
nullptr,
nullptr, &optionsCallback);
529 return loadInfos.front().m_Output;
534 DataStorage::SetOfObjects::Pointer nodeResult = DataStorage::SetOfObjects::New();
535 std::vector<LoadInfo> loadInfos;
536 for (
auto loadInfo : paths)
538 loadInfos.push_back(loadInfo);
540 std::string errMsg =
Load(loadInfos, nodeResult, &storage, optionsCallback);
550 std::vector<BaseData::Pointer> result;
551 std::vector<LoadInfo> loadInfos;
552 for (
auto loadInfo : paths)
554 loadInfos.push_back(loadInfo);
556 std::string errMsg =
Load(loadInfos,
nullptr,
nullptr, optionsCallback);
562 for (std::vector<LoadInfo>::const_iterator iter = loadInfos.begin(), iterEnd = loadInfos.end(); iter != iterEnd;
565 result.insert(result.end(), iter->m_Output.begin(), iter->m_Output.end());
575 if (loadInfos.empty())
577 return "No input files given";
580 int filesToRead = loadInfos.size();
585 std::map<std::string, FileReaderSelector::Item> usedReaderItems;
587 std::vector< std::string > read_files;
588 for (
auto &loadInfo : loadInfos)
590 if(std::find(read_files.begin(), read_files.end(), loadInfo.m_Path) != read_files.end())
593 std::vector<FileReaderSelector::Item> readers = loadInfo.m_ReaderSelector.Get();
597 if (!itksys::SystemTools::FileExists(loadInfo.m_Path.c_str()))
599 errMsg +=
"File '" + loadInfo.m_Path +
"' does not exist\n";
603 errMsg +=
"No reader available for '" + loadInfo.m_Path +
"'\n";
608 bool callOptionsCallback = readers.size() > 1 || !readers.front().GetReader()->GetOptions().empty();
611 std::vector<MimeType> currMimeTypes = loadInfo.m_ReaderSelector.GetMimeTypes();
612 std::string selectedMimeType;
613 for (std::vector<MimeType>::const_iterator mimeTypeIter = currMimeTypes.begin(),
614 mimeTypeIterEnd = currMimeTypes.end();
615 mimeTypeIter != mimeTypeIterEnd;
618 std::map<std::string, FileReaderSelector::Item>::const_iterator oldSelectedItemIter =
619 usedReaderItems.find(mimeTypeIter->GetName());
620 if (oldSelectedItemIter != usedReaderItems.end())
625 for (std::vector<FileReaderSelector::Item>::const_iterator currReaderItem = readers.begin(),
626 currReaderItemEnd = readers.end();
627 currReaderItem != currReaderItemEnd;
630 if (currReaderItem->GetMimeType().GetName() == mimeTypeIter->GetName() &&
631 currReaderItem->GetServiceId() == oldSelectedItemIter->second.GetServiceId() &&
632 currReaderItem->GetConfidenceLevel() >= oldSelectedItemIter->second.GetConfidenceLevel())
635 selectedMimeType = mimeTypeIter->GetName();
636 callOptionsCallback =
false;
637 loadInfo.m_ReaderSelector.Select(oldSelectedItemIter->second.GetServiceId());
638 loadInfo.m_ReaderSelector.GetSelected().GetReader()->SetOptions(
639 oldSelectedItemIter->second.GetReader()->GetOptions());
643 if (!selectedMimeType.empty())
648 if (callOptionsCallback && optionsCallback)
650 callOptionsCallback = (*optionsCallback)(loadInfo);
651 if (!callOptionsCallback && !loadInfo.m_Cancel)
653 usedReaderItems.erase(selectedMimeType);
655 usedReaderItems.insert(std::make_pair(selectedItem.
GetMimeType().
GetName(), selectedItem));
659 if (loadInfo.m_Cancel)
661 errMsg +=
"Reading operation(s) cancelled.";
665 IFileReader *reader = loadInfo.m_ReaderSelector.GetSelected().GetReader();
666 if (reader ==
nullptr)
668 errMsg +=
"Unexpected nullptr reader.";
675 DataStorage::SetOfObjects::Pointer nodes;
678 nodes = reader->
Read(*ds);
680 std::vector< std::string > new_files = reader->
GetReadFiles();
681 read_files.insert( read_files.end(), new_files.begin(), new_files.end() );
685 nodes = DataStorage::SetOfObjects::New();
686 std::vector<mitk::BaseData::Pointer> baseData = reader->
Read();
687 for (
auto iter = baseData.begin(); iter != baseData.end(); ++iter)
689 if (iter->IsNotNull())
692 node->SetData(*iter);
693 nodes->InsertElement(nodes->Size(), node);
697 std::vector< std::string > new_files = reader->
GetReadFiles();
698 read_files.insert( read_files.end(), new_files.begin(), new_files.end() );
701 for (DataStorage::SetOfObjects::ConstIterator nodeIter = nodes->Begin(), nodeIterEnd = nodes->End();
702 nodeIter != nodeIterEnd;
713 data->SetProperty(
"path", pathProp);
715 loadInfo.m_Output.push_back(data);
718 nodeResult->push_back(nodeIter->Value());
722 if (loadInfo.m_Output.empty() || (nodeResult && nodeResult->Size() == 0))
724 errMsg +=
"Unknown read error occurred reading " + loadInfo.m_Path;
727 catch (
const std::exception &e)
729 errMsg +=
"Exception occured when reading file " + loadInfo.m_Path +
":\n" + e.what() +
"\n\n";
752 std::vector<mitk::BaseData::Pointer> data;
753 if (mimetypes.empty())
760 std::vector<us::ServiceReference<IFileReader>> refs = fileReaderRegistry.
GetReferences(mimetypes[0]);
769 data = reader->
Read();
777 Save(data, std::string(), path, options, setPathProperty);
780 void IOUtil::Save(
const BaseData *data,
const std::string &mimeType,
const std::string &path,
bool addExtension,
bool setPathProperty)
786 const std::string &mimeType,
787 const std::string &path,
790 bool setPathProperty)
792 if ((data ==
nullptr) || (data->
IsEmpty()))
793 mitkThrow() <<
"BaseData cannotbe null or empty for save methods in IOUtil.h.";
798 errMsg =
Save(data, mimeType, path,
nullptr, addExtension, setPathProperty);
802 Impl::FixedWriterOptionsFunctor optionsCallback(options);
803 errMsg =
Save(data, mimeType, path, &optionsCallback, addExtension, setPathProperty);
812 void IOUtil::Save(std::vector<IOUtil::SaveInfo> &saveInfos,
bool setPathProperty)
814 std::string errMsg =
Save(saveInfos,
nullptr, setPathProperty);
822 const std::string &mimeTypeName,
823 const std::string &path,
826 bool setPathProperty)
830 return "No output filename given";
837 SaveInfo saveInfo(data, mimeType, path);
839 std::string ext = itksys::SystemTools::GetFilenameExtension(path);
843 return std::string(
"No suitable writer found for the current data of type ") + data->GetNameOfClass() +
844 (mimeType.
IsValid() ? (std::string(
" and mime-type ") + mimeType.
GetName()) : std::string()) +
845 (ext.empty() ? std::string() : (std::string(
" with extension ") + ext));
849 if (ext.empty() && addExtension)
854 std::vector<SaveInfo> infos;
855 infos.push_back(saveInfo);
856 return Save(infos, optionsCallback, setPathProperty);
861 if (saveInfos.empty())
863 return "No data for saving available";
866 int filesToWrite = saveInfos.size();
871 std::set<SaveInfo> usedSaveInfos;
873 for (
auto &saveInfo : saveInfos)
875 const std::string baseDataType = saveInfo.m_BaseData->GetNameOfClass();
877 std::vector<FileWriterSelector::Item> writers = saveInfo.m_WriterSelector.Get();
882 errMsg += std::string(
"No writer available for ") + baseDataType +
" data.\n";
886 bool callOptionsCallback = writers.size() > 1 || !writers[0].GetWriter()->GetOptions().empty();
890 auto oldSaveInfoIter = usedSaveInfos.find(saveInfo);
891 if (oldSaveInfoIter != usedSaveInfos.end())
897 oldSaveInfoIter->m_WriterSelector.Get(oldSaveInfoIter->m_WriterSelector.GetSelectedId());
898 for (std::vector<FileWriterSelector::Item>::const_iterator currWriterItem = writers.begin(),
899 currWriterItemEnd = writers.end();
900 currWriterItem != currWriterItemEnd;
903 if (currWriterItem->GetServiceId() == oldSelectedItem.
GetServiceId() &&
907 callOptionsCallback =
false;
908 saveInfo.m_WriterSelector.Select(oldSaveInfoIter->m_WriterSelector.GetSelectedId());
915 if (callOptionsCallback && optionsCallback)
917 callOptionsCallback = (*optionsCallback)(saveInfo);
918 if (!callOptionsCallback && !saveInfo.m_Cancel)
920 usedSaveInfos.erase(saveInfo);
921 usedSaveInfos.insert(saveInfo);
925 if (saveInfo.m_Cancel)
927 errMsg +=
"Writing operation(s) cancelled.";
931 IFileWriter *writer = saveInfo.m_WriterSelector.GetSelected().GetWriter();
932 if (writer ==
nullptr)
934 errMsg +=
"Unexpected nullptr writer.";
944 catch (
const std::exception &e)
946 errMsg += std::string(
"Exception occurred when writing to ") + saveInfo.m_Path +
":\n" + e.what() +
"\n";
950 saveInfo.m_BaseData->GetPropertyList()->SetStringProperty(
"path", saveInfo.m_Path.c_str());
967 void IOUtil::Impl::SetDefaultDataNodeProperties(
DataNode *node,
const std::string &filePath)
1002 : m_BaseData(baseData),
1003 m_WriterSelector(baseData, mimeType.
GetName(), path),
1004 m_MimeType(mimeType.IsValid() ? mimeType
1006 (m_WriterSelector.IsEmpty() ?
1009 m_WriterSelector.GetDefault().GetMimeType()
mitk::BaseProperty * GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer=nullptr, bool fallBackOnDataProperties=true) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList of the rendere...
void Progress(unsigned int steps=1)
Sets the current amount of progress to current progress + steps.
static char GetDirectorySeparator()
virtual bool IsEmpty() const
Check whether object contains data (at least at one point in time), e.g., a set of points may be empt...
Data management class that handles 'was created by' relations.
FileWriterSelector m_WriterSelector
Contains a set of IFileWriter objects.
void SetVisibility(bool visible, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="visible")
Convenience method for setting visibility properties (instances of BoolProperty)
static IMimeTypeProvider * GetMimeTypeProvider(us::ModuleContext *context=us::GetModuleContext())
Get an IMimeTypeProvider instance.
mitk::IFileReader * GetReader(const ReaderReference &ref, us::ModuleContext *context=us::GetModuleContext())
Base of all data objects.
static std::string GetTempPath()
virtual MimeType GetMimeTypeForName(const std::string &name) const =0
long GetServiceId() const
DataCollection - Class to facilitate loading/accessing structured data.
std::map< std::string, us::Any > Options
Options for reading or writing data.
LoadInfo(const std::string &path)
const BaseData * m_BaseData
The BaseData object to save.
virtual void SetOutputLocation(const std::string &location)=0
Set the output location.
std::string GetName() const
static ProgressBar * GetInstance()
static method to get the GUI dependent ProgressBar-instance so the methods for steps to do and progre...
bool operator<(const SaveInfo &other) const
virtual std::vector< itk::SmartPointer< BaseData > > Read()=0
Reads the specified file or input stream and returns its contents.
std::vector< std::string > GetExtensions() const
IFileWriter::ConfidenceLevel GetConfidenceLevel() const
static std::string NO_NAME_VALUE()
void SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName="", bool fallBackOnDefaultContext=false) override
Add new or change existent property.
MimeType m_MimeType
The selected mime-type, used to restrict results from FileWriterSelector.
virtual void SetOptions(const Options &options)=0
static int mkstemps_compat(char *tmpl, int suffixlen)
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
SaveInfo(const BaseData *baseData, const MimeType &mimeType, const std::string &path)
static std::string GetLastErrorStr()
virtual void SetInput(const std::string &location)=0
Set the input location.
virtual std::vector< std::string > GetReadFiles()=0
MimeType GetMimeType() const
static char * mkdtemps_compat(char *tmpl, int suffixlen)
virtual void Write()=0
Write the input data.
itk::VectorContainer< unsigned int, DataNode::Pointer > SetOfObjects
A Container of objects that is used as a result set of GetSubset() query operations (Set of...
The MimeType class represens a registered mime-type. It is an immutable wrapper for mitk::CustomMimeT...
static std::string CreateTemporaryDirectory(const std::string &templateName="XXXXXX", std::string path=std::string())
static std::string GetProgramPath()
mitk::BaseProperty::Pointer GetProperty(const char *propertyKey) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList, and set it to this, respectively;.
virtual Options GetOptions() const =0
returns a list of the supported options
void AddStepsToDo(unsigned int steps)
Adds steps to totalSteps.
bool m_Cancel
Flag indicating if sub-sequent save operations are to be canceled.
static void Save(const mitk::BaseData *data, const std::string &path, bool setPathProperty=false)
Save a mitk::BaseData instance.
static std::string CreateTemporaryFile(std::ofstream &tmpStream, const std::string &templateName="XXXXXX", std::string path=std::string())
std::string m_Path
The path to write the BaseData object to.
std::string GetResourcePath() const
static std::string GetName(std::string fileName, std::string suffix)
MimeType GetMimeType() const
A RAII helper class for core service objects.
static std::vector< ReaderReference > GetReferences(const MimeType &mimeType, us::ModuleContext *context=us::GetModuleContext())
The common interface for all MITK file readers.
The common interface of all MITK file writers.
itk::SmartPointer< Self > Pointer
IFileWriter * GetWriter() const
static DataStorage::SetOfObjects::Pointer Load(const std::string &path, DataStorage &storage, const ReaderOptionsFunctorBase *optionsCallback=nullptr)
Load a file into the given DataStorage.
Class for nodes of the DataTree.
static const char validLetters[]
virtual std::vector< MimeType > GetMimeTypesForFile(const std::string &filePath) const =0