35 #include <itksys/SystemTools.hxx>
38 #include <vtkPolyData.h>
39 #include <vtkSmartPointer.h>
40 #include <vtkTriangleFilter.h>
47 #ifdef US_PLATFORM_POSIX
48 return std::string(strerror(errno));
52 DWORD dw = GetLastError();
54 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
57 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
62 std::string errMsg((LPCTSTR)lpMsgBuf);
70 #ifdef US_PLATFORM_WINDOWS
76 #define S_IRUSR S_IREAD
77 #define S_IWUSR S_IWRITE
82 #include <sys/types.h>
90 static const char validLetters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
95 static unsigned long long value = 0;
96 int savedErrno = errno;
99 #define ATTEMPTS_MIN (62 * 62 * 62)
103 #if ATTEMPTS_MIN < TMP_MAX
104 const unsigned int attempts = TMP_MAX;
109 const int len = strlen(tmpl);
110 if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen],
"XXXXXX", 6))
117 char *XXXXXX = &tmpl[len - 6 - suffixlen];
120 #ifdef US_PLATFORM_WINDOWS
126 GetSystemTime(&stNow);
127 stNow.wMilliseconds = 500;
128 if (!SystemTimeToFileTime(&stNow, &ftNow))
133 unsigned long long randomTimeBits = ((
static_cast<unsigned long long>(ftNow.dwHighDateTime) << 32) |
134 static_cast<unsigned long long>(ftNow.dwLowDateTime));
135 value = randomTimeBits ^
static_cast<unsigned long long>(GetCurrentThreadId());
140 gettimeofday(&tv, NULL);
141 unsigned long long randomTimeBits =
142 ((
static_cast<unsigned long long>(tv.tv_usec) << 32) |
static_cast<unsigned long long>(tv.tv_sec));
143 value = randomTimeBits ^
static_cast<unsigned long long>(getpid());
147 for (
unsigned int count = 0; count < attempts; value += 7777, ++count)
149 unsigned long long v = value;
164 int fd = open(tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
170 else if (errno != EEXIST)
184 static unsigned long long value = 0;
185 int savedErrno = errno;
188 #define ATTEMPTS_MIN (62 * 62 * 62)
192 #if ATTEMPTS_MIN < TMP_MAX
193 const unsigned int attempts = TMP_MAX;
198 const int len = strlen(tmpl);
199 if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen],
"XXXXXX", 6))
206 char *XXXXXX = &tmpl[len - 6 - suffixlen];
209 #ifdef US_PLATFORM_WINDOWS
215 GetSystemTime(&stNow);
216 stNow.wMilliseconds = 500;
217 if (!SystemTimeToFileTime(&stNow, &ftNow))
222 unsigned long long randomTimeBits = ((
static_cast<unsigned long long>(ftNow.dwHighDateTime) << 32) |
223 static_cast<unsigned long long>(ftNow.dwLowDateTime));
224 value = randomTimeBits ^
static_cast<unsigned long long>(GetCurrentThreadId());
229 gettimeofday(&tv, NULL);
230 unsigned long long randomTimeBits =
231 ((
static_cast<unsigned long long>(tv.tv_usec) << 32) |
static_cast<unsigned long long>(tv.tv_sec));
232 value = randomTimeBits ^
static_cast<unsigned long long>(getpid());
236 unsigned int count = 0;
237 for (; count < attempts; value += 7777, ++count)
239 unsigned long long v = value;
254 #ifdef US_PLATFORM_WINDOWS
255 int fd = _mkdir(tmpl);
257 int fd = mkdir(tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
264 else if (errno != EEXIST)
284 struct FixedReaderOptionsFunctor :
public ReaderOptionsFunctorBase
287 virtual bool operator()(LoadInfo &loadInfo)
override
289 IFileReader *reader = loadInfo.m_ReaderSelector.GetSelected().GetReader();
292 reader->SetOptions(m_Options);
301 struct FixedWriterOptionsFunctor :
public WriterOptionsFunctorBase
304 virtual bool operator()(SaveInfo &saveInfo)
override
306 IFileWriter *writer = saveInfo.m_WriterSelector.GetSelected().GetWriter();
309 writer->SetOptions(m_Options);
320 static void SetDefaultDataNodeProperties(
mitk::DataNode *node,
const std::string &filePath = std::string());
323 #ifdef US_PLATFORM_WINDOWS
327 std::size_t index = std::string(path, GetModuleFileName(NULL, path, 512)).find_last_of(
'\\');
328 return std::string(path, index);
330 #elif defined(US_PLATFORM_APPLE)
331 #include <mach-o/dyld.h>
335 uint32_t size =
sizeof(path);
336 if (_NSGetExecutablePath(path, &size) == 0)
338 std::size_t index = std::string(path).find_last_of(
'/');
339 std::string strPath = std::string(path, index);
344 return std::string();
348 #include <sys/types.h>
352 std::stringstream ss;
353 ss <<
"/proc/" << getpid() <<
"/exe";
354 char proc[512] = {0};
355 ssize_t ch = readlink(ss.str().c_str(), proc, 512);
357 return std::string();
358 std::size_t index = std::string(proc).find_last_of(
'/');
359 return std::string(proc, index);
365 #ifdef US_PLATFORM_WINDOWS
374 static std::string result;
377 #ifdef US_PLATFORM_WINDOWS
378 char tempPathTestBuffer[1];
380 if (bufferLength == 0)
384 std::vector<char> tempPath(bufferLength);
386 if (bufferLength == 0)
390 result.assign(tempPath.begin(), tempPath.begin() +
static_cast<std::size_t
>(bufferLength));
401 ofstream tmpOutputStream;
403 tmpOutputStream.close();
409 return CreateTemporaryFile(f, std::ios_base::out | std::ios_base::trunc, templateName, path);
413 std::ios_base::openmode mode,
414 const std::string &templateName,
422 path += templateName;
424 std::vector<char> dst_path(path.begin(), path.end());
425 dst_path.push_back(
'\0');
427 std::size_t lastX = path.find_last_of(
'X');
428 std::size_t firstX = path.find_last_not_of(
'X', lastX);
429 int firstNonX = firstX == std::string::npos ? -1 : firstX - 1;
430 while (lastX != std::string::npos && (lastX - firstNonX) < 6)
432 lastX = path.find_last_of(
'X', firstX);
433 firstX = path.find_last_not_of(
'X', lastX);
434 firstNonX = firstX == std::string::npos ? -1 : firstX - 1;
436 std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1;
441 path.assign(dst_path.begin(), dst_path.end() - 1);
442 f.open(path.c_str(), mode | std::ios_base::out | std::ios_base::trunc);
460 std::vector<char> dst_path(path.begin(), path.end());
461 dst_path.push_back(
'\0');
463 std::size_t lastX = path.find_last_of(
'X');
464 std::size_t firstX = path.find_last_not_of(
'X', lastX);
465 int firstNonX = firstX == std::string::npos ? -1 : firstX - 1;
466 while (lastX != std::string::npos && (lastX - firstNonX) < 6)
468 lastX = path.find_last_of(
'X', firstX);
469 firstX = path.find_last_not_of(
'X', lastX);
470 firstNonX = firstX == std::string::npos ? -1 : firstX - 1;
472 std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1;
479 path.assign(dst_path.begin(), dst_path.end() - 1);
485 std::vector<std::string> paths;
486 paths.push_back(path);
487 return Load(paths, storage);
494 std::vector<LoadInfo> loadInfos;
495 loadInfos.push_back(
LoadInfo(path));
497 Impl::FixedReaderOptionsFunctor optionsCallback(options);
498 std::string errMsg =
Load(loadInfos, nodeResult, &storage, &optionsCallback);
508 std::vector<std::string> paths;
509 paths.push_back(path);
515 std::vector<LoadInfo> loadInfos;
516 loadInfos.push_back(
LoadInfo(path));
517 Impl::FixedReaderOptionsFunctor optionsCallback(options);
518 std::string errMsg =
Load(loadInfos, NULL, NULL, &optionsCallback);
523 return loadInfos.front().m_Output;
529 std::vector<LoadInfo> loadInfos;
530 for (
auto loadInfo : paths)
532 loadInfos.push_back(loadInfo);
534 std::string errMsg =
Load(loadInfos, nodeResult, &storage, NULL);
542 std::vector<BaseData::Pointer>
IOUtil::Load(
const std::vector<std::string> &paths)
544 std::vector<BaseData::Pointer> result;
545 std::vector<LoadInfo> loadInfos;
546 for (
auto loadInfo : paths)
548 loadInfos.push_back(loadInfo);
550 std::string errMsg =
Load(loadInfos, NULL, NULL, NULL);
556 for (std::vector<LoadInfo>::const_iterator iter = loadInfos.begin(), iterEnd = loadInfos.end(); iter != iterEnd;
559 result.insert(result.end(), iter->m_Output.begin(), iter->m_Output.end());
566 return static_cast<int>(
Load(fileNames, ds)->Size());
572 Load(fileNames, *ds);
573 return ds.GetPointer();
579 std::vector<BaseData::Pointer> baseDataList = Load(path);
582 assert(!baseDataList.empty());
583 return baseDataList.front();
591 node->SetData(baseData);
592 Impl::SetDefaultDataNodeProperties(node, path);
603 mitkThrow() << path <<
" is not a mitk::Image but a " << baseData->GetNameOfClass();
612 if (surface.IsNull())
614 mitkThrow() << path <<
" is not a mitk::Surface but a " << baseData->GetNameOfClass();
623 if (pointset.IsNull())
625 mitkThrow() << path <<
" is not a mitk::PointSet but a " << baseData->GetNameOfClass();
635 if (loadInfos.empty())
637 return "No input files given";
640 int filesToRead = loadInfos.size();
645 std::map<std::string, FileReaderSelector::Item> usedReaderItems;
647 for (
auto &loadInfo : loadInfos)
649 std::vector<FileReaderSelector::Item> readers = loadInfo.m_ReaderSelector.Get();
653 if (!itksys::SystemTools::FileExists(loadInfo.m_Path.c_str()))
655 errMsg +=
"File '" + loadInfo.m_Path +
"' does not exist\n";
659 errMsg +=
"No reader available for '" + loadInfo.m_Path +
"'\n";
664 bool callOptionsCallback = readers.size() > 1 || !readers.front().GetReader()->GetOptions().empty();
667 std::vector<MimeType> currMimeTypes = loadInfo.m_ReaderSelector.GetMimeTypes();
668 std::string selectedMimeType;
669 for (std::vector<MimeType>::const_iterator mimeTypeIter = currMimeTypes.begin(),
670 mimeTypeIterEnd = currMimeTypes.end();
671 mimeTypeIter != mimeTypeIterEnd;
674 std::map<std::string, FileReaderSelector::Item>::const_iterator oldSelectedItemIter =
675 usedReaderItems.find(mimeTypeIter->GetName());
676 if (oldSelectedItemIter != usedReaderItems.end())
681 for (std::vector<FileReaderSelector::Item>::const_iterator currReaderItem = readers.begin(),
682 currReaderItemEnd = readers.end();
683 currReaderItem != currReaderItemEnd;
686 if (currReaderItem->GetMimeType().GetName() == mimeTypeIter->GetName() &&
687 currReaderItem->GetServiceId() == oldSelectedItemIter->second.GetServiceId() &&
688 currReaderItem->GetConfidenceLevel() >= oldSelectedItemIter->second.GetConfidenceLevel())
691 selectedMimeType = mimeTypeIter->GetName();
692 callOptionsCallback =
false;
693 loadInfo.m_ReaderSelector.Select(oldSelectedItemIter->second.GetServiceId());
694 loadInfo.m_ReaderSelector.GetSelected().GetReader()->SetOptions(
695 oldSelectedItemIter->second.GetReader()->GetOptions());
699 if (!selectedMimeType.empty())
704 if (callOptionsCallback && optionsCallback)
706 callOptionsCallback = (*optionsCallback)(loadInfo);
707 if (!callOptionsCallback && !loadInfo.m_Cancel)
709 usedReaderItems.erase(selectedMimeType);
711 usedReaderItems.insert(std::make_pair(selectedItem.
GetMimeType().
GetName(), selectedItem));
715 if (loadInfo.m_Cancel)
717 errMsg +=
"Reading operation(s) cancelled.";
721 IFileReader *reader = loadInfo.m_ReaderSelector.GetSelected().GetReader();
724 errMsg +=
"Unexpected NULL reader.";
734 nodes = reader->
Read(*ds);
739 std::vector<mitk::BaseData::Pointer> baseData = reader->
Read();
740 for (std::vector<mitk::BaseData::Pointer>::iterator iter = baseData.begin(); iter != baseData.end(); ++iter)
742 if (iter->IsNotNull())
745 node->SetData(*iter);
746 nodes->InsertElement(nodes->Size(), node);
751 for (DataStorage::SetOfObjects::ConstIterator nodeIter = nodes->Begin(), nodeIterEnd = nodes->End();
752 nodeIter != nodeIterEnd;
763 data->SetProperty(
"path", pathProp);
765 loadInfo.m_Output.push_back(data);
768 nodeResult->push_back(nodeIter->Value());
772 if (loadInfo.m_Output.empty() || (nodeResult && nodeResult->Size() == 0))
774 errMsg +=
"Unknown read error occurred reading " + loadInfo.m_Path;
777 catch (
const std::exception &e)
779 errMsg +=
"Exception occured when reading file " + loadInfo.m_Path +
":\n" + e.what() +
"\n\n";
802 std::vector<mitk::BaseData::Pointer> data;
803 if (mimetypes.empty())
810 std::vector<us::ServiceReference<IFileReader>> refs = fileReaderRegistry.
GetReferences(mimetypes[0]);
819 data = reader->
Read();
827 Save(data, std::string(), path, options);
830 void IOUtil::Save(
const BaseData *data,
const std::string &mimeType,
const std::string &path,
bool addExtension)
836 const std::string &mimeType,
837 const std::string &path,
841 if ((data == NULL) || (data->
IsEmpty()))
842 mitkThrow() <<
"BaseData cannotbe null or empty for save methods in IOUtil.h.";
847 errMsg =
Save(data, mimeType, path, NULL, addExtension);
851 Impl::FixedWriterOptionsFunctor optionsCallback(options);
852 errMsg =
Save(data, mimeType, path, &optionsCallback, addExtension);
863 std::string errMsg =
Save(saveInfos, NULL);
884 Save(pointset, path);
895 const std::string &mimeTypeName,
896 const std::string &path,
902 return "No output filename given";
909 SaveInfo saveInfo(data, mimeType, path);
911 std::string ext = itksys::SystemTools::GetFilenameExtension(path);
915 return std::string(
"No suitable writer found for the current data of type ") + data->GetNameOfClass() +
916 (mimeType.
IsValid() ? (std::string(
" and mime-type ") + mimeType.
GetName()) : std::string()) +
917 (ext.empty() ? std::string() : (std::string(
" with extension ") + ext));
921 if (ext.empty() && addExtension)
926 std::vector<SaveInfo> infos;
927 infos.push_back(saveInfo);
928 return Save(infos, optionsCallback);
933 if (saveInfos.empty())
935 return "No data for saving available";
938 int filesToWrite = saveInfos.size();
943 std::set<SaveInfo> usedSaveInfos;
945 for (
auto &saveInfo : saveInfos)
947 const std::string baseDataType = saveInfo.m_BaseData->GetNameOfClass();
949 std::vector<FileWriterSelector::Item> writers = saveInfo.m_WriterSelector.Get();
954 errMsg += std::string(
"No writer available for ") + baseDataType +
" data.\n";
958 bool callOptionsCallback = writers.size() > 1 || !writers[0].GetWriter()->GetOptions().empty();
962 std::set<SaveInfo>::const_iterator oldSaveInfoIter = usedSaveInfos.find(saveInfo);
963 if (oldSaveInfoIter != usedSaveInfos.end())
969 oldSaveInfoIter->m_WriterSelector.Get(oldSaveInfoIter->m_WriterSelector.GetSelectedId());
970 for (std::vector<FileWriterSelector::Item>::const_iterator currWriterItem = writers.begin(),
971 currWriterItemEnd = writers.end();
972 currWriterItem != currWriterItemEnd;
975 if (currWriterItem->GetServiceId() == oldSelectedItem.
GetServiceId() &&
979 callOptionsCallback =
false;
980 saveInfo.m_WriterSelector.Select(oldSaveInfoIter->m_WriterSelector.GetSelectedId());
981 saveInfo.m_WriterSelector.GetSelected().GetWriter()->SetOptions(oldSelectedItem.
GetWriter()->
GetOptions());
987 if (callOptionsCallback && optionsCallback)
989 callOptionsCallback = (*optionsCallback)(saveInfo);
990 if (!callOptionsCallback && !saveInfo.m_Cancel)
992 usedSaveInfos.erase(saveInfo);
993 usedSaveInfos.insert(saveInfo);
997 if (saveInfo.m_Cancel)
999 errMsg +=
"Writing operation(s) cancelled.";
1003 IFileWriter *writer = saveInfo.m_WriterSelector.GetSelected().GetWriter();
1006 errMsg +=
"Unexpected NULL writer.";
1016 catch (
const std::exception &e)
1018 errMsg += std::string(
"Exception occurred when writing to ") + saveInfo.m_Path +
":\n" + e.what() +
"\n";
1024 if (!errMsg.empty())
1035 void IOUtil::Impl::SetDefaultDataNodeProperties(
DataNode *node,
const std::string &filePath)
1043 if (nameProp.IsNull() || (strcmp(nameProp->GetValue(),
"No Name!") == 0))
1048 if (baseDataNameProp.IsNull() || (strcmp(baseDataNameProp->GetValue(),
"No Name!") == 0))
1070 : m_BaseData(baseData),
1071 m_WriterSelector(baseData, mimeType.
GetName(), path),
1072 m_MimeType(mimeType.IsValid() ? mimeType
1074 (m_WriterSelector.IsEmpty() ?
1077 m_WriterSelector.GetDefault().GetMimeType()
1086 int r = strcmp(m_BaseData->GetNameOfClass(), other.
m_BaseData->GetNameOfClass());
void Progress(unsigned int steps=1)
Sets the current amount of progress to current progress + steps.
Class for storing surfaces (vtkPolyData).
static mitk::Surface::Pointer LoadSurface(const std::string &path)
LoadSurface Convenience method to load an arbitrary mitkSurface.
static void Save(const mitk::BaseData *data, const std::string &path)
Save a mitk::BaseData instance.
static char GetDirectorySeparator()
Data management class that handles 'was created by' relations.
std::string GetResourcePath() const
itk::SmartPointer< Self > Pointer
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.
itk::VectorContainer< unsigned int, mitk::DataNode::Pointer > SetOfObjects
A Container of objects that is used as a result set of GetSubset() query operations (Set of...
mitk::IFileReader * GetReader(const ReaderReference &ref, us::ModuleContext *context=us::GetModuleContext())
Base of all data objects.
long GetServiceId() const
static std::string GetTempPath()
virtual MimeType GetMimeTypeForName(const std::string &name) const =0
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)
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
const BaseData * m_BaseData
The BaseData object to save.
virtual void SetOutputLocation(const std::string &location)=0
Set the output location.
mitk::BaseProperty * GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer=nullptr) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList of the rendere...
static mitk::BaseData::Pointer LoadBaseData(const std::string &path)
Create a BaseData object from the given file.
static bool SaveSurface(mitk::Surface::Pointer surface, const std::string &path)
SaveSurface Convenience method to save an arbitrary mitkSurface.
std::vector< std::string > GetExtensions() const
static ProgressBar * GetInstance()
static method to get the GUI dependent ProgressBar-instance so the methods for steps to do and progre...
virtual std::vector< itk::SmartPointer< BaseData > > Read()=0
Reads the specified file or input stream and returns its contents.
bool operator<(const SaveInfo &other) const
std::string GetName() const
MimeType m_MimeType
The selected mime-type, used to restrict results from FileWriterSelector.
static bool SaveImage(mitk::Image::Pointer image, const std::string &path)
SaveImage Convenience method to save an arbitrary mitkImage.
static bool SaveBaseData(mitk::BaseData *data, const std::string &path)
SaveBaseData Convenience method to save arbitrary baseData.
static int mkstemps_compat(char *tmpl, int suffixlen)
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.
Data structure which stores a set of points. Superclass of mitk::Mesh.
static int LoadFiles(const std::vector< std::string > &fileNames, DataStorage &storage)
Image class for storing images.
static char * mkdtemps_compat(char *tmpl, int suffixlen)
static mitk::PointSet::Pointer LoadPointSet(const std::string &path)
LoadPointSet Convenience method to load an arbitrary mitkPointSet.
virtual void Write()=0
Write the input data.
The MimeType class represens a registered mime-type. It is an immutable wrapper for mitk::CustomMimeT...
static mitk::DataNode::Pointer LoadDataNode(const std::string &path)
LoadDataNode Method to load an arbitrary DataNode.
static std::string CreateTemporaryDirectory(const std::string &templateName="XXXXXX", std::string path=std::string())
static std::string GetProgramPath()
virtual Options GetOptions() const =0
returns a list of the supported options
void AddStepsToDo(unsigned int steps)
Adds steps to totalSteps.
static std::string CreateTemporaryFile(std::ofstream &tmpStream, const std::string &templateName="XXXXXX", std::string path=std::string())
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...
MimeType GetMimeType() const
static std::string GetName(std::string fileName, std::string suffix)
A RAII helper class for core service objects.
static DataStorage::SetOfObjects::Pointer Load(const std::string &path, DataStorage &storage)
Load a file into the given DataStorage.
void SetProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer=nullptr)
Set the property (instance of BaseProperty) with key propertyKey in the PropertyList of the renderer ...
static std::vector< ReaderReference > GetReferences(const MimeType &mimeType, us::ModuleContext *context=us::GetModuleContext())
IFileWriter::ConfidenceLevel GetConfidenceLevel() const
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;.
The common interface for all MITK file readers.
The common interface of all MITK file writers.
MimeType GetMimeType() const
IFileWriter * GetWriter() const
static bool SavePointSet(mitk::PointSet::Pointer pointset, const std::string &path)
SavePointSet Convenience method to save an mitkPointSet.
itk::SmartPointer< Self > Pointer
static mitk::Image::Pointer LoadImage(const std::string &path)
LoadImage Convenience method to load an arbitrary mitkImage.
Class for nodes of the DataTree.
static const char validLetters[]
virtual std::vector< MimeType > GetMimeTypesForFile(const std::string &filePath) const =0
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.