diff --git a/Core/Code/IO/mitkAbstractFileIO.cpp b/Core/Code/IO/mitkAbstractFileIO.cpp new file mode 100644 index 0000000000..61293e7d42 --- /dev/null +++ b/Core/Code/IO/mitkAbstractFileIO.cpp @@ -0,0 +1,188 @@ +/*=================================================================== + +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 "mitkAbstractFileIO.h" + +namespace mitk { + +AbstractFileIO::ReaderOptions AbstractFileIO::GetReaderOptions() const +{ + return AbstractFileReader::GetOptions(); +} + +us::Any AbstractFileIO::GetReaderOption(const std::string& name) const +{ + return AbstractFileReader::GetOption(name); +} + +void AbstractFileIO::SetReaderOptions(const AbstractFileIO::ReaderOptions& options) +{ + AbstractFileReader::SetOptions(options); +} + +void AbstractFileIO::SetReaderOption(const std::string& name, const us::Any& value) +{ + AbstractFileReader::SetOption(name, value); +} + +std::pair, us::ServiceRegistration > +AbstractFileIO::RegisterService(us::ModuleContext* context) +{ + std::pair, us::ServiceRegistration > result; + result.first = this->AbstractFileReader::RegisterService(context); + result.second = this->AbstractFileWriter::RegisterService(context); + return result; +} + +AbstractFileIO::AbstractFileIO() +{ +} + +AbstractFileIO::AbstractFileIO(const AbstractFileIO& other) + : AbstractFileReader(other) + , AbstractFileWriter(other) +{ +} + +AbstractFileIO::AbstractFileIO(const std::string& baseDataType, + const AbstractFileIO::MimeType& mimeType, + const std::string& description) + : AbstractFileReader(mimeType, description) + , AbstractFileWriter() +{ + this->AbstractFileWriter::SetBaseDataType(baseDataType); + this->AbstractFileWriter::SetMimeType(mimeType); +} + +AbstractFileIO::AbstractFileIO(const std::string& baseDataType, const std::string& extension, const std::string& description) + : AbstractFileReader(extension, description) +{ + this->AbstractFileWriter::SetBaseDataType(baseDataType); + this->AbstractFileWriter::AddExtension(extension); + this->AbstractFileWriter::SetDescription(description); +} + +void AbstractFileIO::SetMimeType(const std::string& mimeType) +{ + this->AbstractFileReader::SetMimeType(mimeType); + this->AbstractFileWriter::SetMimeType(mimeType); +} + +std::string AbstractFileIO::GetMimeType() const +{ + std::string mimeType = this->AbstractFileReader::GetMimeType(); + if (mimeType != this->AbstractFileWriter::GetMimeType()) + { + MITK_WARN << "Reader and writer mime-tpyes are different, using the mime-type from IFileReader"; + } + return mimeType; +} + +void AbstractFileIO::SetCategory(const std::string& category) +{ + this->AbstractFileReader::SetCategory(category); + this->AbstractFileWriter::SetCategory(category); +} + +std::string AbstractFileIO::GetCategory() const +{ + std::string category = this->AbstractFileReader::GetCategory(); + if (category != this->AbstractFileWriter::GetCategory()) + { + MITK_WARN << "Reader and writer mime-tpyes are different, using the mime-type from IFileReader"; + } + return category; +} + +std::vector AbstractFileIO::GetExtensions() const +{ + std::vector extensions = this->AbstractFileReader::GetExtensions(); + if (extensions != this->AbstractFileWriter::GetExtensions()) + { + MITK_WARN << "Reader and writer extensions are different, using extensions from IFileReader"; + } + return extensions; +} + +void AbstractFileIO::AddExtension(const std::string& extension) +{ + this->AbstractFileReader::AddExtension(extension); + this->AbstractFileWriter::AddExtension(extension); +} + +void AbstractFileIO::SetReaderDescription(const std::string& description) +{ + this->AbstractFileReader::SetDescription(description); +} + +std::string AbstractFileIO::GetReaderDescription() const +{ + return this->AbstractFileReader::GetDescription(); +} + +void AbstractFileIO::SetWriterDescription(const std::string& description) +{ + this->AbstractFileWriter::SetDescription(description); +} + +std::string AbstractFileIO::GetWriterDescription() const +{ + return this->AbstractFileWriter::GetDescription(); +} + +void AbstractFileIO::SetDefaultReaderOptions(const AbstractFileIO::ReaderOptions& defaultOptions) +{ + this->AbstractFileReader::SetDefaultOptions(defaultOptions); +} + +AbstractFileIO::ReaderOptions AbstractFileIO::GetDefaultReaderOptions() const +{ + return this->AbstractFileReader::GetDefaultOptions(); +} + +void AbstractFileIO::SetDefaultWriterOptions(const AbstractFileIO::WriterOptions& defaultOptions) +{ + this->AbstractFileWriter::SetDefaultOptions(defaultOptions); +} + +AbstractFileIO::WriterOptions AbstractFileIO::GetDefaultWriterOptions() const +{ + return this->AbstractFileWriter::GetDefaultOptions(); +} + +void AbstractFileIO::SetReaderRanking(int ranking) +{ + this->AbstractFileReader::SetRanking(ranking); +} + +int AbstractFileIO::GetReaderRanking() const +{ + return this->AbstractFileReader::GetRanking(); +} + +void AbstractFileIO::SetWriterRanking(int ranking) +{ + this->AbstractFileWriter::SetRanking(ranking); +} + +int AbstractFileIO::GetWriterRanking() const +{ + return this->AbstractFileWriter::GetRanking(); +} + + + +} diff --git a/Core/Code/IO/mitkAbstractFileIO.h b/Core/Code/IO/mitkAbstractFileIO.h new file mode 100644 index 0000000000..aca3673bd4 --- /dev/null +++ b/Core/Code/IO/mitkAbstractFileIO.h @@ -0,0 +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 MITKABSTRACTFILEIO_H +#define MITKABSTRACTFILEIO_H + +#include "mitkAbstractFileReader.h" +#include "mitkAbstractFileWriter.h" + +namespace mitk { + +class MITK_CORE_EXPORT AbstractFileIO : public AbstractFileReader, public AbstractFileWriter +{ +public: + + typedef IFileReader::Options ReaderOptions; + typedef IFileWriter::Options WriterOptions; + + ReaderOptions GetReaderOptions() const; + us::Any GetReaderOption(const std::string &name) const; + + void SetReaderOptions(const ReaderOptions& options); + void SetReaderOption(const std::string& name, const us::Any& value); + + std::pair, us::ServiceRegistration > + RegisterService(us::ModuleContext* context = us::GetModuleContext()); + +protected: + + typedef AbstractFileReader::MimeType MimeType; + + AbstractFileIO(); + + AbstractFileIO(const AbstractFileIO& other); + + /** + * Associate this reader instance with the given MIME type. + * + * @param mimeType The mime type this reader can read. + * @param description A human readable description of this reader. + * + * @throws std::invalid_argument if \c mimeType is empty. + * + * @see RegisterService + */ + explicit AbstractFileIO(const std::string& baseDataType, const MimeType& mimeType, + const std::string& description); + + /** + * Associate this reader with the given file extension. + * + * Additonal file extensions can be added by sub-classes by calling AddExtension + * or SetExtensions. + * + * @param extension The file extension (without a leading period) for which a registered + * IMimeType object is looked up and associated with this reader instance. + * @param description A human readable description of this reader. + * + * @see RegisterService + */ + explicit AbstractFileIO(const std::string& baseDataType, const std::string& extension, + const std::string& description); + + void SetMimeType(const std::string& mimeType); + + /** + * @return The mime-type this reader can handle. + */ + std::string GetMimeType() const; + + void SetCategory(const std::string& category); + std::string GetCategory() const; + + std::vector GetExtensions() const; + void AddExtension(const std::string& extension); + + void SetReaderDescription(const std::string& description); + std::string GetReaderDescription() const; + + void SetWriterDescription(const std::string& description); + std::string GetWriterDescription() const; + + void SetDefaultReaderOptions(const ReaderOptions& defaultOptions); + ReaderOptions GetDefaultReaderOptions() const; + + void SetDefaultWriterOptions(const WriterOptions& defaultOptions); + WriterOptions GetDefaultWriterOptions() const; + + /** + * \brief Set the service ranking for this file reader. + * + * Default is zero and should only be chosen differently for a reason. + * The ranking is used to determine which reader to use if several + * equivalent readers have been found. + * It may be used to replace a default reader from MITK in your own project. + * E.g. if you want to use your own reader for nrrd files instead of the default, + * implement it and give it a higher ranking than zero. + */ + void SetReaderRanking(int ranking); + int GetReaderRanking() const; + + void SetWriterRanking(int ranking); + int GetWriterRanking() const; + +private: + + AbstractFileIO& operator=(const AbstractFileIO& other); + + virtual AbstractFileIO* Clone() const = 0; + +}; + +} + +#endif // MITKABSTRACTFILEIO_H diff --git a/Core/Code/IO/mitkAbstractFileReader.cpp b/Core/Code/IO/mitkAbstractFileReader.cpp index 616869e162..28c3bf1b0b 100644 --- a/Core/Code/IO/mitkAbstractFileReader.cpp +++ b/Core/Code/IO/mitkAbstractFileReader.cpp @@ -1,382 +1,396 @@ /*=================================================================== 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 #include #include #include #include #include #include #include namespace mitk { class AbstractFileReader::Impl : public FileReaderWriterBase { public: Impl() : FileReaderWriterBase() , m_PrototypeFactory(NULL) {} Impl(const Impl& other) : FileReaderWriterBase(other) , m_PrototypeFactory(NULL) {} us::PrototypeServiceFactory* m_PrototypeFactory; + us::ServiceRegistration m_Reg; }; AbstractFileReader::AbstractFileReader() : d(new Impl) { } AbstractFileReader::~AbstractFileReader() { + UnregisterService(); + delete d->m_PrototypeFactory; d->UnregisterMimeType(); } AbstractFileReader::AbstractFileReader(const AbstractFileReader& other) : d(new Impl(*other.d.get())) { } AbstractFileReader::AbstractFileReader(const MimeType& mimeType, const std::string& description) : d(new Impl) { d->SetMimeType(mimeType); d->SetDescription(description); } AbstractFileReader::AbstractFileReader(const std::string& extension, const std::string& description) : d(new Impl) { d->SetDescription(description); d->AddExtension(extension); } ////////////////////// Reading ///////////////////////// std::vector > AbstractFileReader::Read(const std::string& path) { if (!itksys::SystemTools::FileExists(path.c_str())) { mitkThrow() << "File '" + path + "' not found."; } std::ifstream stream; stream.open(path.c_str(), std::ios_base::in | std::ios_base::binary); try { return this->Read(stream); } catch (mitk::Exception& e) { mitkReThrow(e) << "Error reading file '" << path << "'"; } catch (const std::exception& e) { mitkThrow() << "Error reading file '" << path << "': " << e.what(); } } std::vector > AbstractFileReader::Read(std::istream& stream) { // Create a temporary file and copy the data to it std::ofstream tmpOutputStream; std::string tmpFilePath = IOUtil::CreateTemporaryFile(tmpOutputStream); tmpOutputStream << stream.rdbuf(); tmpOutputStream.close(); // Now read from the temporary file std::vector > result = this->Read(tmpFilePath); std::remove(tmpFilePath.c_str()); return result; } DataStorage::SetOfObjects::Pointer AbstractFileReader::Read(const std::string& path, DataStorage& ds) { DataStorage::SetOfObjects::Pointer result = DataStorage::SetOfObjects::New(); std::vector data = this->Read(path); for (std::vector::iterator iter = data.begin(); iter != data.end(); ++iter) { mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(*iter); this->SetDefaultDataNodeProperties(node, path); ds.Add(node); result->InsertElement(result->Size(), node); } return result; } DataStorage::SetOfObjects::Pointer AbstractFileReader::Read(std::istream& stream, DataStorage& ds) { DataStorage::SetOfObjects::Pointer result = DataStorage::SetOfObjects::New(); std::vector data = this->Read(stream); for (std::vector::iterator iter = data.begin(); iter != data.end(); ++iter) { mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(*iter); this->SetDefaultDataNodeProperties(node, std::string()); ds.Add(node); result->InsertElement(result->Size(), node); } return result; } //////////// µS Registration & Properties ////////////// us::ServiceRegistration AbstractFileReader::RegisterService(us::ModuleContext* context) { if (d->m_PrototypeFactory) return us::ServiceRegistration(); if(context == NULL) { context = us::GetModuleContext(); } d->RegisterMimeType(context); if (this->GetMimeType().empty()) { - MITK_WARN << "Not registering reader " << typeid(this).name() << " due to empty MIME type."; + MITK_WARN << "Not registering reader due to empty MIME type."; return us::ServiceRegistration(); } struct PrototypeFactory : public us::PrototypeServiceFactory { AbstractFileReader* const m_Prototype; PrototypeFactory(AbstractFileReader* prototype) : m_Prototype(prototype) {} us::InterfaceMap GetService(us::Module* /*module*/, const us::ServiceRegistrationBase& /*registration*/) { return us::MakeInterfaceMap(m_Prototype->Clone()); } void UngetService(us::Module* /*module*/, const us::ServiceRegistrationBase& /*registration*/, const us::InterfaceMap& service) { delete us::ExtractInterface(service); } }; d->m_PrototypeFactory = new PrototypeFactory(this); us::ServiceProperties props = this->GetServiceProperties(); - return context->RegisterService(d->m_PrototypeFactory, props); + d->m_Reg = context->RegisterService(d->m_PrototypeFactory, props); + return d->m_Reg; +} + +void AbstractFileReader::UnregisterService() +{ + try + { + d->m_Reg.Unregister(); + } + catch (const std::exception&) + {} } us::ServiceProperties AbstractFileReader::GetServiceProperties() const { us::ServiceProperties result; result[IFileReader::PROP_DESCRIPTION()] = this->GetDescription(); result[IFileReader::PROP_MIMETYPE()] = this->GetMimeType(); result[us::ServiceConstants::SERVICE_RANKING()] = this->GetRanking(); return result; } us::ServiceRegistration AbstractFileReader::RegisterMimeType(us::ModuleContext* context) { return d->RegisterMimeType(context); } void AbstractFileReader::SetMimeType(const std::string& mimeType) { d->SetMimeType(mimeType); } void AbstractFileReader::SetCategory(const std::string& category) { d->SetCategory(category); } void AbstractFileReader::AddExtension(const std::string& extension) { d->AddExtension(extension); } void AbstractFileReader::SetDescription(const std::string& description) { d->SetDescription(description); } void AbstractFileReader::SetRanking(int ranking) { d->SetRanking(ranking); } int AbstractFileReader::GetRanking() const { return d->GetRanking(); } //////////////////////// Options /////////////////////// void AbstractFileReader::SetDefaultOptions(const IFileReader::Options& defaultOptions) { d->SetDefaultOptions(defaultOptions); } IFileReader::Options AbstractFileReader::GetDefaultOptions() const { return d->GetDefaultOptions(); } IFileReader::Options AbstractFileReader::GetOptions() const { return d->GetOptions(); } us::Any AbstractFileReader::GetOption(const std::string& name) const { return d->GetOption(name); } void AbstractFileReader::SetOptions(const Options& options) { d->SetOptions(options); } void AbstractFileReader::SetOption(const std::string& name, const us::Any& value) { d->SetOption(name, value); } ////////////////// MISC ////////////////// bool AbstractFileReader::CanRead(const std::string& path) const { if (!itksys::SystemTools::FileExists(path.c_str(), true)) { return false; } // Default implementation only checks if extension is correct std::string extension = itksys::SystemTools::GetFilenameExtension(path); extension = extension.substr(1, extension.size()-1); if (!d->HasExtension(extension)) { return false; } std::ifstream stream(path.c_str()); return this->CanRead(stream); } bool AbstractFileReader::CanRead(std::istream& stream) const { return stream.good(); } void AbstractFileReader::AddProgressCallback(const ProgressCallback& callback) { d->AddProgressCallback(callback); } void AbstractFileReader::RemoveProgressCallback(const ProgressCallback& callback) { d->RemoveProgressCallback(callback); } ////////////////// µS related Getters ////////////////// std::string AbstractFileReader::GetCategory() const { return d->GetCategory(); } std::string AbstractFileReader::GetMimeType() const { return d->GetMimeType(); } std::vector AbstractFileReader::GetExtensions() const { return d->GetExtensions(); } std::string AbstractFileReader::GetDescription() const { return d->GetDescription(); } AbstractFileReader::MimeType::MimeType(const std::string& mimeType) : std::string(mimeType) { if (this->empty()) { throw std::invalid_argument("MIME type must not be empty."); } } AbstractFileReader::MimeType::MimeType() { } void AbstractFileReader::SetDefaultDataNodeProperties(DataNode* node, const std::string& filePath) { // path if (!filePath.empty()) { 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 = filebasename; nameProp = mitk::StringProperty::New(itksys::SystemTools::GetFilenameWithoutExtension(itksys::SystemTools::GetFilenameName(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); } } } diff --git a/Core/Code/IO/mitkAbstractFileReader.h b/Core/Code/IO/mitkAbstractFileReader.h index 5f7e7628e5..cbbead95b3 100644 --- a/Core/Code/IO/mitkAbstractFileReader.h +++ b/Core/Code/IO/mitkAbstractFileReader.h @@ -1,219 +1,220 @@ /*=================================================================== 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 AbstractFileReader_H_HEADER_INCLUDED_C1E7E521 #define AbstractFileReader_H_HEADER_INCLUDED_C1E7E521 // Macro #include // MITK #include #include #include // Microservices #include #include #include namespace us { struct PrototypeServiceFactory; } namespace mitk { /** * @brief Base class for creating mitk::BaseData objects from files or streams. * @ingroup Process */ class MITK_CORE_EXPORT AbstractFileReader : public mitk::IFileReader { public: /** * @brief Reads the given \c path and creates a list BaseData objects. * * The default implementation opens a std::ifstream in binary mode for reading * and passed the stream to Read(std::istream&). * * @param path The absolute path to a file include the file name extension. * @return */ virtual std::vector > Read(const std::string& path); virtual std::vector > Read(std::istream& stream) = 0; virtual DataStorage::SetOfObjects::Pointer Read(const std::string& path, mitk::DataStorage& ds); virtual DataStorage::SetOfObjects::Pointer Read(std::istream& stream, mitk::DataStorage& ds); virtual Options GetOptions() const; virtual us::Any GetOption(const std::string &name) const; virtual void SetOptions(const Options& options); virtual void SetOption(const std::string& name, const us::Any& value); /** * @brief Checks if the specified path can be read. * * The default implementation checks if the path exists and contains a * file extension associated with the mime-type of this reader. * It then creates a std::ifstream object for the given path and * calls CanRead(const std::istream&). * * @param path The absolute path to a file. * @return \c true if the file can be read, \c false otherwise. */ virtual bool CanRead(const std::string& path) const; /** * @brief Checks if the specified input stream can be read. * * @param stream The stream to be read. * @return \c true if the stream is good, \c false otherwise. */ virtual bool CanRead(std::istream& stream) const; virtual void AddProgressCallback(const ProgressCallback& callback); virtual void RemoveProgressCallback(const ProgressCallback& callback); /** * Associate this reader with the MIME type returned by the current IMimeTypeProvider * service for the provided extension if the MIME type exists, otherwise registers * a new MIME type when RegisterService() is called. * * If no MIME type for \c extension is already registered, a call to RegisterService() * will register a new MIME type and associate this reader instance with it. The MIME * type id can be set via SetMimeType() or it will be auto-generated using \c extension, * having the form "application/vnd.mitk.". * * @param extension The file extension (without a leading period) for which a registered * IMimeType object is looked up and associated with this reader instance. * @param description A human readable description of this reader. */ us::ServiceRegistration RegisterService(us::ModuleContext* context = us::GetModuleContext()); + void UnregisterService(); protected: class MITK_CORE_EXPORT MimeType : public std::string { public: MimeType(const std::string& mimeType); private: MimeType(); friend class AbstractFileReader; }; AbstractFileReader(); ~AbstractFileReader(); AbstractFileReader(const AbstractFileReader& other); /** * Associate this reader instance with the given MIME type. * * @param mimeType The mime type this reader can read. * @param description A human readable description of this reader. * * @throws std::invalid_argument if \c mimeType is empty. * * @see RegisterService */ explicit AbstractFileReader(const MimeType& mimeType, const std::string& description); /** * Associate this reader with the given file extension. * * Additonal file extensions can be added by sub-classes by calling AddExtension * or SetExtensions. * * @param extension The file extension (without a leading period) for which a registered * IMimeType object is looked up and associated with this reader instance. * @param description A human readable description of this reader. * * @see RegisterService */ explicit AbstractFileReader(const std::string& extension, const std::string& description); virtual us::ServiceProperties GetServiceProperties() const; /** * Registers a new IMimeType service object. * * This method is called from RegisterService and the default implementation * registers a new IMimeType service object if all of the following conditions * are true: * * - The reader * * @param context * @return * @throws std::invalid_argument if \c context is NULL. */ virtual us::ServiceRegistration RegisterMimeType(us::ModuleContext* context); void SetMimeType(const std::string& mimeType); /** * @return The mime-type this reader can handle. */ std::string GetMimeType() const; void SetCategory(const std::string& category); std::string GetCategory() const; std::vector GetExtensions() const; void AddExtension(const std::string& extension); void SetDescription(const std::string& description); std::string GetDescription() const; void SetDefaultOptions(const Options& defaultOptions); Options GetDefaultOptions() const; /** * \brief Set the service ranking for this file reader. * * Default is zero and should only be chosen differently for a reason. * The ranking is used to determine which reader to use if several * equivalent readers have been found. * It may be used to replace a default reader from MITK in your own project. * E.g. if you want to use your own reader for nrrd files instead of the default, * implement it and give it a higher ranking than zero. */ void SetRanking(int ranking); int GetRanking() const; virtual void SetDefaultDataNodeProperties(DataNode* node, const std::string& filePath); private: AbstractFileReader& operator=(const AbstractFileReader& other); virtual mitk::IFileReader* Clone() const = 0; class Impl; std::auto_ptr d; }; } // namespace mitk #endif /* AbstractFileReader_H_HEADER_INCLUDED_C1E7E521 */ diff --git a/Core/Code/IO/mitkAbstractFileWriter.cpp b/Core/Code/IO/mitkAbstractFileWriter.cpp index df219b0e74..c5fcccff65 100644 --- a/Core/Code/IO/mitkAbstractFileWriter.cpp +++ b/Core/Code/IO/mitkAbstractFileWriter.cpp @@ -1,310 +1,324 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include namespace mitk { class AbstractFileWriter::Impl : public FileReaderWriterBase { public: Impl() : FileReaderWriterBase() , m_PrototypeFactory(NULL) {} Impl(const Impl& other) : FileReaderWriterBase(other) , m_BaseDataType(other.m_BaseDataType) , m_PrototypeFactory(NULL) {} std::string m_BaseDataType; us::PrototypeServiceFactory* m_PrototypeFactory; + us::ServiceRegistration m_Reg; }; AbstractFileWriter::AbstractFileWriter() : d(new Impl) { } AbstractFileWriter::~AbstractFileWriter() { + UnregisterService(); + delete d->m_PrototypeFactory; d->UnregisterMimeType(); } AbstractFileWriter::AbstractFileWriter(const AbstractFileWriter& other) : d(new Impl(*other.d.get())) { } AbstractFileWriter::AbstractFileWriter(const std::string& baseDataType, const MimeType& mimeType, const std::string& description) : d(new Impl) { d->m_BaseDataType = baseDataType; d->SetMimeType(mimeType); d->SetDescription(description); } AbstractFileWriter::AbstractFileWriter(const std::string& baseDataType, const std::string& extension, const std::string& description) : d(new Impl) { d->m_BaseDataType = baseDataType; d->SetDescription(description); d->AddExtension(extension); } ////////////////////// Writing ///////////////////////// void AbstractFileWriter::Write(const BaseData* data, const std::string& path) { std::ofstream stream; stream.open(path.c_str()); try { this->Write(data, stream); } catch(mitk::Exception& e) { mitkReThrow(e) << "Error writing file '" << path << "'"; } catch(const std::exception& e) { mitkThrow() << "Error writing file '" << path << "': " << e.what(); } } void AbstractFileWriter::Write(const BaseData* data, std::ostream& stream) { // Create a temporary file and write the data to it std::ofstream tmpOutputStream; std::string tmpFilePath = IOUtil::CreateTemporaryFile(tmpOutputStream); this->Write(data, tmpFilePath); tmpOutputStream.close(); // Now copy the contents std::ifstream tmpInputStream(tmpFilePath.c_str(), std::ios_base::binary); stream << tmpInputStream.rdbuf(); tmpInputStream.close(); std::remove(tmpFilePath.c_str()); } //////////// µS Registration & Properties ////////////// us::ServiceRegistration AbstractFileWriter::RegisterService(us::ModuleContext* context) { if (d->m_PrototypeFactory) return us::ServiceRegistration(); if(context == NULL) { context = us::GetModuleContext(); } d->RegisterMimeType(context); if (this->GetMimeType().empty()) { - MITK_WARN << "Not registering writer " << typeid(this).name() << " due to empty MIME type."; + MITK_WARN << "Not registering writer due to empty MIME type."; return us::ServiceRegistration(); } struct PrototypeFactory : public us::PrototypeServiceFactory { AbstractFileWriter* const m_Prototype; PrototypeFactory(AbstractFileWriter* prototype) : m_Prototype(prototype) {} us::InterfaceMap GetService(us::Module* /*module*/, const us::ServiceRegistrationBase& /*registration*/) { return us::MakeInterfaceMap(m_Prototype->Clone()); } void UngetService(us::Module* /*module*/, const us::ServiceRegistrationBase& /*registration*/, const us::InterfaceMap& service) { delete us::ExtractInterface(service); } }; d->m_PrototypeFactory = new PrototypeFactory(this); us::ServiceProperties props = this->GetServiceProperties(); - return context->RegisterService(d->m_PrototypeFactory, props); + d->m_Reg = context->RegisterService(d->m_PrototypeFactory, props); + return d->m_Reg; +} + +void AbstractFileWriter::UnregisterService() +{ + try + { + d->m_Reg.Unregister(); + } + catch (const std::exception&) + {} } us::ServiceProperties AbstractFileWriter::GetServiceProperties() const { us::ServiceProperties result; result[IFileWriter::PROP_DESCRIPTION()] = this->GetDescription(); result[IFileWriter::PROP_MIMETYPE()] = this->GetMimeType(); result[IFileWriter::PROP_BASEDATA_TYPE()] = d->m_BaseDataType; result[us::ServiceConstants::SERVICE_RANKING()] = this->GetRanking(); // for (IFileWriter::OptionList::const_iterator it = d->m_Options.begin(); it != d->m_Options.end(); ++it) // { // result[it->first] = std::string("true"); // } return result; } std::string AbstractFileWriter::GetMimeType() const { return d->GetMimeType(); } us::ServiceRegistration AbstractFileWriter::RegisterMimeType(us::ModuleContext* context) { return d->RegisterMimeType(context); } void AbstractFileWriter::SetMimeType(const std::string& mimeType) { d->SetMimeType(mimeType); } void AbstractFileWriter::SetRanking(int ranking) { d->SetRanking(ranking); } //////////////////////// Options /////////////////////// void AbstractFileWriter::SetDefaultOptions(const IFileWriter::Options& defaultOptions) { d->SetDefaultOptions(defaultOptions); } IFileWriter::Options AbstractFileWriter::GetDefaultOptions() const { return d->GetDefaultOptions(); } IFileWriter::Options AbstractFileWriter::GetOptions() const { return d->GetOptions(); } us::Any AbstractFileWriter::GetOption(const std::string& name) const { return d->GetOption(name); } void AbstractFileWriter::SetOption(const std::string& name, const us::Any& value) { d->SetOption(name, value); } void AbstractFileWriter::SetOptions(const Options& options) { d->SetOptions(options); } ////////////////// MISC ////////////////// void AbstractFileWriter::AddProgressCallback(const ProgressCallback& callback) { d->AddProgressCallback(callback); } void AbstractFileWriter::RemoveProgressCallback(const ProgressCallback& callback) { d->RemoveProgressCallback(callback); } ////////////////// µS related Getters ////////////////// int AbstractFileWriter::GetRanking() const { return d->GetRanking(); } std::vector AbstractFileWriter::GetExtensions() const { return d->GetExtensions(); } void AbstractFileWriter::AddExtension(const std::string& extension) { d->AddExtension(extension); } void AbstractFileWriter::SetCategory(const std::string& category) { d->SetCategory(category); } std::string AbstractFileWriter::GetCategory() const { return d->GetCategory(); } void AbstractFileWriter::SetBaseDataType(const std::string& baseDataType) { d->m_BaseDataType = baseDataType; } std::string AbstractFileWriter::GetDescription() const { return d->GetDescription(); } std::string AbstractFileWriter::GetBaseDataType() const { return d->m_BaseDataType; } void AbstractFileWriter::SetDescription(const std::string& description) { d->SetDescription(description); } AbstractFileWriter::MimeType::MimeType(const std::string& mimeType) : std::string(mimeType) { if (this->empty()) { throw std::invalid_argument("MIME type must not be empty."); } } AbstractFileWriter::MimeType::MimeType() { } } diff --git a/Core/Code/IO/mitkAbstractFileWriter.h b/Core/Code/IO/mitkAbstractFileWriter.h index 5395c9d7d9..e55483bed2 100644 --- a/Core/Code/IO/mitkAbstractFileWriter.h +++ b/Core/Code/IO/mitkAbstractFileWriter.h @@ -1,177 +1,178 @@ /*=================================================================== 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 AbstractFileWriter_H_HEADER_INCLUDED_C1E7E521 #define AbstractFileWriter_H_HEADER_INCLUDED_C1E7E521 // Macro #include // MITK #include #include // Microservices #include #include #include #include namespace us { struct PrototypeServiceFactory; } namespace mitk { /** * @brief Base class for writing mitk::BaseData objects to files or streams. * * In general, all file writers should derive from this class, this way it is * made sure that the new implementation is * exposed to the Microservice-Framework and that is automatically available troughout MITK. * The default implementation only requires one Write() * method and the Clone() method to be implemented. * * @ingroup Process */ class MITK_CORE_EXPORT AbstractFileWriter : public mitk::IFileWriter { public: /** * \brief Write the data in data to the the location specified in path */ virtual void Write(const BaseData* data, const std::string& path); /** * \brief Write the data in data to the the stream specified in stream */ virtual void Write(const BaseData* data, std::ostream& stream ) = 0; virtual Options GetOptions() const; virtual us::Any GetOption(const std::string &name) const; virtual void SetOptions(const Options& options); virtual void SetOption(const std::string& name, const us::Any& value); virtual void AddProgressCallback(const ProgressCallback& callback); virtual void RemoveProgressCallback(const ProgressCallback& callback); us::ServiceRegistration RegisterService(us::ModuleContext* context = us::GetModuleContext()); + void UnregisterService(); protected: class MITK_CORE_EXPORT MimeType : public std::string { public: MimeType(const std::string& mimeType); private: MimeType(); friend class AbstractFileReader; }; AbstractFileWriter(); ~AbstractFileWriter(); AbstractFileWriter(const AbstractFileWriter& other); AbstractFileWriter(const std::string& basedataType, const MimeType& mimeType, const std::string& description); AbstractFileWriter(const std::string& basedataType, const std::string& extension, const std::string& description); virtual us::ServiceProperties GetServiceProperties() const; /** * Registers a new IMimeType service object. * * This method is called from RegisterService and the default implementation * registers a new IMimeType service object if all of the following conditions * are true: * * - The writer * * @param context * @return * @throws std::invalid_argument if \c context is NULL. */ virtual us::ServiceRegistration RegisterMimeType(us::ModuleContext* context); void SetMimeType(const std::string& mimeType); /** * @return Get the mime-type this writer can handle. */ std::string GetMimeType() const; void SetCategory(const std::string& category); std::string GetCategory() const; /** * \brief Get file extension that this writer is able to handle. */ std::vector GetExtensions() const; void AddExtension(const std::string& extension); /** * \brief Sets a human readable description of this writer. * * This will be used in file dialogs for example. */ void SetDescription(const std::string& description); std::string GetDescription() const; void SetDefaultOptions(const Options& defaultOptions); Options GetDefaultOptions() const; /** * \brief Set the service ranking for this file writer. * * Default is zero and should only be chosen differently for a reason. * The ranking is used to determine which writer to use if several * equivalent writers have been found. * It may be used to replace a default writer from MITK in your own project. * E.g. if you want to use your own writer for nrrd files instead of the default, * implement it and give it a higher ranking than zero. */ void SetRanking(int ranking); int GetRanking() const; /** * \brief Sets the name of the mitk::Basedata that this writer is able to handle. * * The correct value is the one given as the first parameter in the mitkNewMacro of that BaseData derivate. * You can also retrieve it by calling GetNameOfClass() on an instance of said data. */ void SetBaseDataType(const std::string& baseDataType); virtual std::string GetBaseDataType() const; private: AbstractFileWriter& operator=(const AbstractFileWriter& other); virtual mitk::IFileWriter* Clone() const = 0; class Impl; std::auto_ptr d; }; } // namespace mitk #endif /* AbstractFileWriter_H_HEADER_INCLUDED_C1E7E521 */ diff --git a/Core/Code/Interfaces/mitkIMimeTypeProvider.h b/Core/Code/Interfaces/mitkIMimeTypeProvider.h index 64837684e4..8378f2a564 100644 --- a/Core/Code/Interfaces/mitkIMimeTypeProvider.h +++ b/Core/Code/Interfaces/mitkIMimeTypeProvider.h @@ -1,70 +1,74 @@ /*=================================================================== 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 MITKIMIMETYPEPROVIDER_H #define MITKIMIMETYPEPROVIDER_H #include #include #include namespace mitk { /** * @brief The IMimeTypeProvider service interface allows to query all registered * mime types. * * Mime types are added to the system by registering a service object of type * IMimeType and the registered mime types can be queried bei either using direct * look-ups in the service registry or calling the methods of this service interface. * * This service interface also allows to infer the mime type of a file on the file * system. The heuristics for infering the actual mime type is implementation specific. * * @note This is a core service * * @sa IMimeType * @sa CoreServices::GetMimeTypeProvider() */ struct MITK_CORE_EXPORT IMimeTypeProvider { virtual ~IMimeTypeProvider(); virtual std::vector GetMimeTypes() const = 0; virtual std::vector GetMimeTypesForFile(const std::string& filePath) const = 0; virtual std::vector GetMimeTypesForExtension(const std::string& extension) const = 0; virtual std::vector GetMimeTypesForCategory(const std::string& category) const = 0; virtual std::string GetDescription(const std::string& mimeType) const = 0; virtual std::vector GetExtensions(const std::string& mimeType) const = 0; virtual std::string GetCategory(const std::string& mimeType) const = 0; + /** + * @brief Get a sorted and unique list of mime-type categories. + * @return A sorted, unique list of mime-type categories. + */ virtual std::vector GetCategories() const = 0; }; } US_DECLARE_SERVICE_INTERFACE(mitk::IMimeTypeProvider, "org.mitk.IMimeTypeProvider") #endif // MITKIMIMETYPEPROVIDER_H diff --git a/Core/Code/Internal/mitkCoreActivator.cpp b/Core/Code/Internal/mitkCoreActivator.cpp index 9db8b30ef9..04c581ed48 100644 --- a/Core/Code/Internal/mitkCoreActivator.cpp +++ b/Core/Code/Internal/mitkCoreActivator.cpp @@ -1,425 +1,391 @@ /*=================================================================== 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 "mitkCoreActivator.h" // File IO #include -#include +#include #include #include #include #include // Micro Services #include #include #include #include #include #include #include #include #include #include #include void HandleMicroServicesMessages(us::MsgType type, const char* msg) { switch (type) { case us::DebugMsg: MITK_DEBUG << msg; break; case us::InfoMsg: MITK_INFO << msg; break; case us::WarningMsg: MITK_WARN << msg; break; case us::ErrorMsg: MITK_ERROR << msg; break; } } void AddMitkAutoLoadPaths(const std::string& programPath) { us::ModuleSettings::AddAutoLoadPath(programPath); #ifdef __APPLE__ // Walk up three directories since that is where the .dylib files are located // for build trees. std::string additionalPath = programPath; bool addPath = true; for(int i = 0; i < 3; ++i) { std::size_t index = additionalPath.find_last_of('/'); if (index != std::string::npos) { additionalPath = additionalPath.substr(0, index); } else { addPath = false; break; } } if (addPath) { us::ModuleSettings::AddAutoLoadPath(additionalPath); } #endif } class ShaderRepositoryTracker : public us::ServiceTracker { public: ShaderRepositoryTracker() : Superclass(us::GetModuleContext()) { } virtual void Close() { us::GetModuleContext()->RemoveModuleListener(this, &ShaderRepositoryTracker::HandleModuleEvent); Superclass::Close(); } virtual void Open() { us::GetModuleContext()->AddModuleListener(this, &ShaderRepositoryTracker::HandleModuleEvent); Superclass::Open(); } private: typedef us::ServiceTracker Superclass; TrackedType AddingService(const ServiceReferenceType &reference) { mitk::IShaderRepository* shaderRepo = Superclass::AddingService(reference); if (shaderRepo) { // Add all existing shaders from modules to the new shader repository. // If the shader repository is registered in a modules activator, the // GetLoadedModules() function call below will also return the module // which is currently registering the repository. The HandleModuleEvent // method contains code to avoid double registrations due to a fired // ModuleEvent::LOADED event after the activators Load() method finished. std::vector modules = us::ModuleRegistry::GetLoadedModules(); for (std::vector::const_iterator iter = modules.begin(), endIter = modules.end(); iter != endIter; ++iter) { this->AddModuleShaderToRepository(*iter, shaderRepo); } m_ShaderRepositories.push_back(shaderRepo); } return shaderRepo; } void RemovedService(const ServiceReferenceType& /*reference*/, TrackedType tracked) { m_ShaderRepositories.erase(std::remove(m_ShaderRepositories.begin(), m_ShaderRepositories.end(), tracked), m_ShaderRepositories.end()); } void HandleModuleEvent(const us::ModuleEvent moduleEvent) { if (moduleEvent.GetType() == us::ModuleEvent::LOADED) { std::vector shaderRepos; for (std::map > >::const_iterator shaderMapIter = m_ModuleIdToShaderIds.begin(), shaderMapEndIter = m_ModuleIdToShaderIds.end(); shaderMapIter != shaderMapEndIter; ++shaderMapIter) { if (shaderMapIter->second.find(moduleEvent.GetModule()->GetModuleId()) == shaderMapIter->second.end()) { shaderRepos.push_back(shaderMapIter->first); } } AddModuleShadersToRepositories(moduleEvent.GetModule(), shaderRepos); } else if (moduleEvent.GetType() == us::ModuleEvent::UNLOADED) { RemoveModuleShadersFromRepositories(moduleEvent.GetModule(), m_ShaderRepositories); } } void AddModuleShadersToRepositories(us::Module* module, const std::vector& shaderRepos) { // search and load shader files std::vector shaderResources = module->FindResources("Shaders", "*.xml", true); for (std::vector::iterator i = shaderResources.begin(); i != shaderResources.end(); ++i) { if (*i) { us::ModuleResourceStream rs(*i); for (std::vector::const_iterator shaderRepoIter = shaderRepos.begin(), shaderRepoEndIter = shaderRepos.end(); shaderRepoIter != shaderRepoEndIter; ++shaderRepoIter) { int id = (*shaderRepoIter)->LoadShader(rs, i->GetBaseName()); if (id >= 0) { m_ModuleIdToShaderIds[*shaderRepoIter][module->GetModuleId()].push_back(id); } } rs.seekg(0, std::ios_base::beg); } } } void AddModuleShaderToRepository(us::Module* module, mitk::IShaderRepository* shaderRepo) { std::vector shaderRepos; shaderRepos.push_back(shaderRepo); this->AddModuleShadersToRepositories(module, shaderRepos); } void RemoveModuleShadersFromRepositories(us::Module* module, const std::vector& shaderRepos) { for (std::vector::const_iterator shaderRepoIter = shaderRepos.begin(), shaderRepoEndIter = shaderRepos.end(); shaderRepoIter != shaderRepoEndIter; ++shaderRepoIter) { std::map >& moduleIdToShaderIds = m_ModuleIdToShaderIds[*shaderRepoIter]; std::map >::iterator shaderIdsIter = moduleIdToShaderIds.find(module->GetModuleId()); if (shaderIdsIter != moduleIdToShaderIds.end()) { for (std::vector::iterator idIter = shaderIdsIter->second.begin(); idIter != shaderIdsIter->second.end(); ++idIter) { (*shaderRepoIter)->UnloadShader(*idIter); } moduleIdToShaderIds.erase(shaderIdsIter); } } } private: // Maps to each shader repository a map containing module ids and related // shader registration ids std::map > > m_ModuleIdToShaderIds; std::vector m_ShaderRepositories; }; void MitkCoreActivator::Load(us::ModuleContext* context) { // Handle messages from CppMicroServices us::installMsgHandler(HandleMicroServicesMessages); this->m_Context = context; // Add the current application directory to the auto-load paths. // This is useful for third-party executables. std::string programPath = mitk::IOUtil::GetProgramPath(); if (programPath.empty()) { MITK_WARN << "Could not get the program path."; } else { AddMitkAutoLoadPaths(programPath); } m_ShaderRepositoryTracker.reset(new ShaderRepositoryTracker); //m_RenderingManager = mitk::RenderingManager::New(); //context->RegisterService(renderingManager.GetPointer()); m_PlanePositionManager.reset(new mitk::PlanePositionManagerService); context->RegisterService(m_PlanePositionManager.get()); m_PropertyAliases.reset(new mitk::PropertyAliases); context->RegisterService(m_PropertyAliases.get()); m_PropertyDescriptions.reset(new mitk::PropertyDescriptions); context->RegisterService(m_PropertyDescriptions.get()); m_PropertyExtensions.reset(new mitk::PropertyExtensions); context->RegisterService(m_PropertyExtensions.get()); m_PropertyFilters.reset(new mitk::PropertyFilters); context->RegisterService(m_PropertyFilters.get()); m_MimeTypeProvider.reset(new mitk::MimeTypeProvider); m_MimeTypeProvider->Start(); m_MimeTypeProviderReg = context->RegisterService(m_MimeTypeProvider.get()); this->RegisterMimeTypes(); this->RegisterItkReaderWriter(); // Add custom Reader / Writer Services m_FileReaders.push_back(new mitk::PointSetReaderService()); m_FileWriters.push_back(new mitk::PointSetWriterService()); m_FileReaders.push_back(new mitk::RawImageFileReader()); // Explicitly load the LegacyIO module us::SharedLibrary legacyIOLib(programPath, "MitkLegacyIO"); legacyIOLib.Load(); m_ShaderRepositoryTracker->Open(); /* There IS an option to exchange ALL vtkTexture instances against vtkNeverTranslucentTextureFactory. This code is left here as a reminder, just in case we might need to do that some time. vtkNeverTranslucentTextureFactory* textureFactory = vtkNeverTranslucentTextureFactory::New(); vtkObjectFactory::RegisterFactory( textureFactory ); textureFactory->Delete(); */ } void MitkCoreActivator::Unload(us::ModuleContext* ) { for(std::vector::iterator iter = m_FileReaders.begin(), endIter = m_FileReaders.end(); iter != endIter; ++iter) { delete *iter; } + for(std::vector::iterator iter = m_FileWriters.begin(), + endIter = m_FileWriters.end(); iter != endIter; ++iter) + { + delete *iter; + } + + for(std::vector::iterator iter = m_FileIOs.begin(), + endIter = m_FileIOs.end(); iter != endIter; ++iter) + { + delete *iter; + } + // The mitk::ModuleContext* argument of the Unload() method // will always be 0 for the Mitk library. It makes no sense // to use it at this stage anyway, since all libraries which // know about the module system have already been unloaded. // we need to close the internal service tracker of the // MimeTypeProvider class here. Otherwise it // would hold on to the ModuleContext longer than it is // actually valid. m_MimeTypeProviderReg.Unregister(); m_MimeTypeProvider->Stop(); m_ShaderRepositoryTracker->Close(); } void MitkCoreActivator::RegisterMimeTypes() { // Register some default mime-types // 3D Images std::vector mimeTypeExtensions; mimeTypeExtensions.push_back("dc3"); mimeTypeExtensions.push_back("dcm"); RegisterMimeType("application/dicom", "Images", "Dicom Images", mimeTypeExtensions); RegisterMimeType("application/vnd.mitk.pic", "Images", "DKFZ PIC Format", "pic"); RegisterMimeType("application/vnd.mitk.pic+gz", "Images", "DKFZ Compressed PIC Format", "pic.gz"); // REMOVE: Test multiple mime types for same extension //RegisterMimeType("application/vnd.fancy", "Images", "Fancy Compressed PIC Format", "pic.gz"); // 2D Images RegisterMimeType("image/bmp", "2D Images", "Bitmap Image", "bmp"); } void MitkCoreActivator::RegisterItkReaderWriter() { - std::list possibleImageIO; std::list allobjects = itk::ObjectFactoryBase::CreateAllInstance("itkImageIOBase"); for (std::list::iterator i = allobjects.begin(), endIter = allobjects.end(); i != endIter; ++i) { itk::ImageIOBase* io = dynamic_cast(i->GetPointer()); if (io) { - if(!io->GetSupportedReadExtensions().empty()) - { - possibleImageIO.push_back(io); - } - else - { - MITK_INFO << "ImageIO factory " << io->GetNameOfClass() << " does not report its supported read extensions."; - } + m_FileIOs.push_back(new mitk::ItkImageIO(io)); } else { MITK_WARN << "Error ImageIO factory did not return an ImageIOBase: " << ( *i )->GetNameOfClass(); } } - for (std::list::iterator k = possibleImageIO.begin(), - endIter = possibleImageIO.end(); k != endIter; ++k) - { - m_FileReaders.push_back(new mitk::ItkFileReaderService((*k)->GetSupportedReadExtensions(), "ITK Image Reader")); - } - - // Some ITK ImageIOBase sub-classes do not report supported read extensions. - // Registering them manually here. - std::vector extensions; - - extensions.clear(); - extensions.push_back("gdcm"); - m_FileReaders.push_back(new mitk::ItkFileReaderService(extensions, "ITK Image Reader")); - - extensions.clear(); - extensions.push_back("png"); - extensions.push_back("PNG"); - m_FileReaders.push_back(new mitk::ItkFileReaderService(extensions, "ITK Image Reader")); - - extensions.clear(); - extensions.push_back("spr"); - m_FileReaders.push_back(new mitk::ItkFileReaderService(extensions, "ITK Image Reader")); - - extensions.clear(); - extensions.push_back("gipl"); - extensions.push_back("gipl.gz"); - m_FileReaders.push_back(new mitk::ItkFileReaderService(extensions, "ITK Image Reader")); - - extensions.clear(); - extensions.push_back("hdf"); - extensions.push_back("h4"); - extensions.push_back("hdf4"); - extensions.push_back("h5"); - extensions.push_back("hdf5"); - extensions.push_back("he4"); - extensions.push_back("he5"); - extensions.push_back("hd5"); - m_FileReaders.push_back(new mitk::ItkFileReaderService(extensions, "ITK Image Reader")); } void MitkCoreActivator::RegisterMimeType(const std::string& id, const std::string& category, const std::string& description, const std::string& extension) { std::vector extensions; extensions.push_back(extension); this->RegisterMimeType(id, category, description, extensions); } void MitkCoreActivator::RegisterMimeType(const std::string& id, const std::string& category, const std::string& description, const std::vector& extensions) { us::ServiceProperties mimeTypeProps; mimeTypeProps[mitk::IMimeType::PROP_ID()] = id; mimeTypeProps[mitk::IMimeType::PROP_CATEGORY()] = category; mimeTypeProps[mitk::IMimeType::PROP_DESCRIPTION()] = description; mimeTypeProps[mitk::IMimeType::PROP_EXTENSIONS()] = extensions; mimeTypeProps[us::ServiceConstants::SERVICE_RANKING()] = -100; m_Context->RegisterService(&m_MimeType, mimeTypeProps); } US_EXPORT_MODULE_ACTIVATOR(MitkCore, MitkCoreActivator) // Call CppMicroservices initialization code at the end of the file. // This especially ensures that VTK object factories have already // been registered (VTK initialization code is injected by implicitly // include VTK header files at the top of this file). US_INITIALIZE_MODULE("MitkCore", "MitkCore") diff --git a/Core/Code/Internal/mitkCoreActivator.h b/Core/Code/Internal/mitkCoreActivator.h index cb3461b5d9..9c72057d0e 100644 --- a/Core/Code/Internal/mitkCoreActivator.h +++ b/Core/Code/Internal/mitkCoreActivator.h @@ -1,87 +1,89 @@ /*=================================================================== 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 MITKCOREACTIVATOR_H_ #define MITKCOREACTIVATOR_H_ // File IO #include #include +#include #include #include #include #include #include #include #include #include // Micro Services #include #include #include #include #include /* * This is the module activator for the "Mitk" module. It registers core services * like ... */ class MitkCoreActivator : public us::ModuleActivator { public: void Load(us::ModuleContext* context); void Unload(us::ModuleContext* ); private: void HandleModuleEvent(const us::ModuleEvent moduleEvent); void RegisterMimeTypes(); void RegisterItkReaderWriter(); void RegisterMimeType(const std::string& id, const std::string& category, const std::string& description, const std::string& extension); void RegisterMimeType(const std::string& id, const std::string& category, const std::string& description, const std::vector& extensions); std::auto_ptr > m_ShaderRepositoryTracker; //mitk::RenderingManager::Pointer m_RenderingManager; std::auto_ptr m_PlanePositionManager; std::auto_ptr m_PropertyAliases; std::auto_ptr m_PropertyDescriptions; std::auto_ptr m_PropertyExtensions; std::auto_ptr m_PropertyFilters; std::auto_ptr m_MimeTypeProvider; // File IO std::vector m_FileReaders; std::vector m_FileWriters; + std::vector m_FileIOs; us::ServiceRegistration m_MimeTypeProviderReg; mitk::SimpleMimeType m_MimeType; us::ModuleContext* m_Context; }; #endif // MITKCOREACTIVATOR_H_ diff --git a/Core/Code/Internal/mitkFileReaderWriterBase.cpp b/Core/Code/Internal/mitkFileReaderWriterBase.cpp index 43dd1b15df..5551b7fb8a 100644 --- a/Core/Code/Internal/mitkFileReaderWriterBase.cpp +++ b/Core/Code/Internal/mitkFileReaderWriterBase.cpp @@ -1,253 +1,253 @@ /*=================================================================== 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 "mitkFileReaderWriterBase.h" #include "mitkLogMacros.h" #include "mitkCoreServices.h" #include "mitkIMimeTypeProvider.h" #include #include namespace mitk { FileReaderWriterBase::FileReaderWriterBase() : m_Ranking(0) { } FileReaderWriterBase::FileReaderWriterBase(const FileReaderWriterBase& other) : m_MimeType(other.m_MimeType) , m_Category(other.m_Category) , m_Extensions(other.m_Extensions) , m_Description(other.m_Description) , m_Ranking(other.m_Ranking) , m_Options(other.m_Options) , m_DefaultOptions(other.m_DefaultOptions) { } FileReaderWriterBase::Options FileReaderWriterBase::GetOptions() const { Options options = m_Options; options.insert(m_DefaultOptions.begin(), m_DefaultOptions.end()); return options; } us::Any FileReaderWriterBase::GetOption(const std::string& name) const { Options::const_iterator iter = m_Options.find(name); if (iter != m_Options.end()) { return iter->second; } iter = m_DefaultOptions.find(name); if (iter != m_DefaultOptions.end()) { return iter->second; } return us::Any(); } void FileReaderWriterBase::SetOptions(const FileReaderWriterBase::Options& options) { for(Options::const_iterator iter = options.begin(), iterEnd = options.end(); iter != iterEnd; ++iter) { this->SetOption(iter->first, iter->second); } } void FileReaderWriterBase::SetOption(const std::string& name, const us::Any& value) { if (m_DefaultOptions.find(name) == m_DefaultOptions.end()) { MITK_WARN << "Ignoring unknown IFileReader option '" << name << "'"; } else { if (value.Empty()) { // an empty Any signals 'reset to default value' m_Options.erase(name); } else { m_Options[name] = value; } } } void FileReaderWriterBase::SetDefaultOptions(const FileReaderWriterBase::Options& defaultOptions) { m_DefaultOptions = defaultOptions; } FileReaderWriterBase::Options FileReaderWriterBase::GetDefaultOptions() const { return m_DefaultOptions; } void FileReaderWriterBase::SetRanking(int ranking) { m_Ranking = ranking; } int FileReaderWriterBase::GetRanking() const { return m_Ranking; } void FileReaderWriterBase::SetMimeType(const std::string& mimeType) { m_MimeType = mimeType; } std::string FileReaderWriterBase::GetMimeType() const { return m_MimeType; } void FileReaderWriterBase::AddExtension(const std::string& extension) { m_Extensions.push_back(extension); } std::vector FileReaderWriterBase::GetExtensions() const { return m_Extensions; } bool FileReaderWriterBase::HasExtension(const std::string& extension) { return std::find(m_Extensions.begin(), m_Extensions.end(), extension) != m_Extensions.end(); } void FileReaderWriterBase::SetDescription(const std::string& description) { m_Description = description; } std::string FileReaderWriterBase::GetDescription() const { return m_Description; } void FileReaderWriterBase::SetCategory(const std::string& category) { m_Category = category; } std::string FileReaderWriterBase::GetCategory() const { return m_Category; } void FileReaderWriterBase::AddProgressCallback(const FileReaderWriterBase::ProgressCallback& callback) { m_ProgressMessage += callback; } void FileReaderWriterBase::RemoveProgressCallback(const FileReaderWriterBase::ProgressCallback& callback) { m_ProgressMessage -= callback; } us::ServiceRegistration FileReaderWriterBase::RegisterMimeType(us::ModuleContext* context) { if (context == NULL) throw std::invalid_argument("The context argument must not be NULL."); const std::string mimeType = this->GetMimeType(); std::vector extensions = this->GetExtensions(); const std::string primaryExtension = extensions.empty() ? "" : extensions.front(); std::sort(extensions.begin(), extensions.end()); extensions.erase(std::unique(extensions.begin(), extensions.end()), extensions.end()); us::ServiceProperties props; props[IMimeType::PROP_ID()] = mimeType; props[IMimeType::PROP_CATEGORY()] = this->GetCategory(); props[IMimeType::PROP_EXTENSIONS()] = extensions; - props[IMimeType::PROP_DESCRIPTION()] = std::string("Generated MIME type from mitk::AbstractFileReader"); + props[IMimeType::PROP_DESCRIPTION()] = std::string("Synthesized MIME type"); props[us::ServiceConstants::SERVICE_RANKING()] = this->GetRanking(); // If the mime type is set and the list of extensions is not empty, // register a new IMimeType service if (!mimeType.empty() && !extensions.empty()) { return context->RegisterService(&m_SimpleMimeType, props); } // If the mime type is set and the list of extensions is empty, // look up the mime type in the registry and print a warning if // there is none if (!mimeType.empty() && extensions.empty()) { if(us::GetModuleContext()->GetServiceReferences(us::LDAPProp(IMimeType::PROP_ID()) == mimeType).empty()) { - MITK_WARN << "Registering a MITK reader with an unknown MIME type " << mimeType; + MITK_WARN << "Registering a MITK reader or writer with an unknown MIME type " << mimeType; } return us::ServiceRegistration(); } // If the mime type is empty, get a mime type using the extensions list assert(mimeType.empty()); mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); if(extensions.empty()) { - MITK_WARN << "Trying to register a MITK reader with an empty mime type and empty extension list."; + MITK_WARN << "Trying to register a MITK reader or writer with an empty mime type and empty extension list."; return us::ServiceRegistration(); } else if(extensions.size() == 1) { // If there is only one extension, try to look-up an existing mime tpye std::vector mimeTypes = mimeTypeProvider->GetMimeTypesForExtension(extensions.front()); if (!mimeTypes.empty()) { m_MimeType = mimeTypes.front(); } } if (m_MimeType.empty()) { // There is no registered mime type for the extension or the extensions // list contains more than one entry. // Register a new mime type by creating a synthetic mime type id from the // first extension in the list m_MimeType = "application/vnd.mitk." + primaryExtension; props[IMimeType::PROP_ID()] = m_MimeType; return context->RegisterService(&m_SimpleMimeType, props); } else { // A mime type for one of the listed extensions was found, do nothing. return us::ServiceRegistration(); } } void FileReaderWriterBase::UnregisterMimeType() { if (m_MimeTypeReg) { m_MimeTypeReg.Unregister(); } } } diff --git a/Core/Code/Internal/mitkItkFileReaderService.cpp b/Core/Code/Internal/mitkItkImageIO.cpp similarity index 58% rename from Core/Code/Internal/mitkItkFileReaderService.cpp rename to Core/Code/Internal/mitkItkImageIO.cpp index f69663beed..a77779ec3f 100644 --- a/Core/Code/Internal/mitkItkFileReaderService.cpp +++ b/Core/Code/Internal/mitkItkImageIO.cpp @@ -1,227 +1,313 @@ /*=================================================================== 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 "mitkItkFileReaderService.h" +#include "mitkItkImageIO.h" #include #include #include #include #include #include +#include -mitk::ItkFileReaderService::ItkFileReaderService(const mitk::ItkFileReaderService& other) - : mitk::AbstractFileReader(other) +namespace mitk { + +ItkImageIO::ItkImageIO(const ItkImageIO& other) + : AbstractFileIO(other) +{ +} + +std::vector ItkImageIO::FixUpImageIOExtensions(const std::string& imageIOName) { + std::vector extensions; + // Try to fix-up some known ITK image IO classes + if (imageIOName == "GiplImageIO") + { + extensions.push_back("gipl"); + extensions.push_back("gipl.gz"); + } + else if (imageIOName == "GDCMImageIO") + { + extensions.push_back("gdcm"); + } + else if (imageIOName == "PNGImageIO") + { + extensions.push_back("png"); + extensions.push_back("PNG"); + } + else if (imageIOName == "StimulateImageIO") + { + extensions.push_back("spr"); + } + else if (imageIOName == "HDF5ImageIO") + { + extensions.push_back("hdf"); + extensions.push_back("h4"); + extensions.push_back("hdf4"); + extensions.push_back("h5"); + extensions.push_back("hdf5"); + extensions.push_back("he4"); + extensions.push_back("he5"); + extensions.push_back("hd5"); + } + + if (!extensions.empty()) + { + MITK_WARN << "Fixing up known extensions for " << imageIOName; + } + + return extensions; } -mitk::ItkFileReaderService::ItkFileReaderService(const std::vector& extensions, - const std::string& category) - : AbstractFileReader() +ItkImageIO::ItkImageIO(itk::ImageIOBase::Pointer imageIO) + : AbstractFileIO() + , m_ImageIO(imageIO) { + std::vector extensions = imageIO->GetSupportedReadExtensions(); + if (extensions.empty()) + { + std::string imageIOName = imageIO->GetNameOfClass(); + MITK_WARN << "ITK ImageIOBase " << imageIOName << " does not provide read extensions"; + extensions = FixUpImageIOExtensions(imageIOName); + } 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()); } - this->AddExtension(extension); + this->AbstractFileReader::AddExtension(extension); } - this->SetCategory(category); - this->SetDescription(category); - m_ServiceReg = this->RegisterService(); -} - -mitk::ItkFileReaderService::~ItkFileReaderService() -{ - try + extensions = imageIO->GetSupportedWriteExtensions(); + if (extensions.empty()) { - m_ServiceReg.Unregister(); + std::string imageIOName = imageIO->GetNameOfClass(); + MITK_WARN << "ITK ImageIOBase " << imageIOName << " does not provide write extensions"; + extensions = FixUpImageIOExtensions(imageIOName); } - catch (const std::exception&) - {} -} + 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()); + } + this->AbstractFileWriter::AddExtension(extension); + } + + this->SetCategory("Images"); + + std::string description = std::string("ITK ") + imageIO->GetNameOfClass(); + this->SetReaderDescription(description); + this->SetWriterDescription(description); -////////////////////// Reading ///////////////////////// + this->RegisterService(); +} -std::vector mitk::ItkFileReaderService::Read(std::istream& stream) +std::vector ItkImageIO::Read(std::istream& stream) { return mitk::AbstractFileReader::Read(stream); } -std::vector mitk::ItkFileReaderService::Read(const std::string& path) +std::vector ItkImageIO::Read(const std::string& path) { - std::vector result; + std::vector result; const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } - mitk::Image::Pointer image = mitk::Image::New(); + Image::Pointer image = Image::New(); const unsigned int MINDIM = 2; const unsigned int MAXDIM = 4; MITK_INFO << "loading " << path << " via itk::ImageIOFactory... " << std::endl; // Check to see if we can read the file given the name or prefix if (path.empty()) { - mitkThrow() << "Empty filename in mitk::ItkFileReaderService "; + mitkThrow() << "Empty filename in mitk::ItkImageIO "; } itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( path.c_str(), itk::ImageIOFactory::ReadMode ); if ( imageIO.IsNull() ) { mitkThrow() << "Could not create itk::ImageIOBase object for filename " << path; } // Got to allocate space for the image. Determine the characteristics of // the image. imageIO->SetFileName( path.c_str() ); imageIO->ReadImageInformation(); unsigned int ndim = imageIO->GetNumberOfDimensions(); if ( ndim < MINDIM || ndim > MAXDIM ) { MITK_WARN << "Sorry, only dimensions 2, 3 and 4 are supported. The given file has " << ndim << " dimensions! Reading as 4D."; ndim = MAXDIM; } itk::ImageIORegion ioRegion( ndim ); itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize(); itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex(); unsigned int dimensions[ MAXDIM ]; dimensions[ 0 ] = 0; dimensions[ 1 ] = 0; dimensions[ 2 ] = 0; dimensions[ 3 ] = 0; ScalarType spacing[ MAXDIM ]; spacing[ 0 ] = 1.0f; spacing[ 1 ] = 1.0f; spacing[ 2 ] = 1.0f; spacing[ 3 ] = 1.0f; Point3D origin; origin.Fill(0); unsigned int i; for ( i = 0; i < ndim ; ++i ) { ioStart[ i ] = 0; ioSize[ i ] = imageIO->GetDimensions( i ); if(iGetDimensions( i ); spacing[ i ] = imageIO->GetSpacing( i ); if(spacing[ i ] <= 0) spacing[ i ] = 1.0f; } if(i<3) { origin[ i ] = imageIO->GetOrigin( i ); } } ioRegion.SetSize( ioSize ); ioRegion.SetIndex( ioStart ); MITK_INFO << "ioRegion: " << ioRegion << std::endl; imageIO->SetIORegion( ioRegion ); void* buffer = new unsigned char[imageIO->GetImageSizeInBytes()]; imageIO->Read( buffer ); image->Initialize( MakePixelType(imageIO), ndim, dimensions ); image->SetImportChannel( buffer, 0, Image::ManageMemory ); // access direction of itk::Image and include spacing mitk::Matrix3D matrix; matrix.SetIdentity(); unsigned int j, itkDimMax3 = (ndim >= 3? 3 : ndim); for ( i=0; i < itkDimMax3; ++i) for( j=0; j < itkDimMax3; ++j ) matrix[i][j] = imageIO->GetDirection(j)[i]; // re-initialize PlaneGeometry with origin and direction PlaneGeometry* planeGeometry = image->GetSlicedGeometry(0)->GetPlaneGeometry(0); planeGeometry->SetOrigin(origin); planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix); // re-initialize SlicedGeometry3D SlicedGeometry3D* slicedGeometry = image->GetSlicedGeometry(0); slicedGeometry->InitializeEvenlySpaced(planeGeometry, image->GetDimension(2)); slicedGeometry->SetSpacing(spacing); MITK_INFO << slicedGeometry->GetCornerPoint(false,false,false); MITK_INFO << slicedGeometry->GetCornerPoint(true,true,true); // re-initialize TimeGeometry ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(slicedGeometry, image->GetDimension(3)); image->SetTimeGeometry(timeGeometry); buffer = NULL; MITK_INFO << "number of image components: "<< image->GetPixelType().GetNumberOfComponents() << std::endl; + const itk::MetaDataDictionary& dictionary = imageIO->GetMetaDataDictionary(); + for (itk::MetaDataDictionary::ConstIterator iter = dictionary.Begin(), iterEnd = dictionary.End(); + iter != iterEnd; ++iter) + { + std::string key = std::string("meta.") + iter->first; + if (iter->second->GetMetaDataObjectTypeInfo() == typeid(std::string)) + { + std::string value = dynamic_cast*>(iter->second.GetPointer())->GetMetaDataObjectValue(); + image->SetProperty(key.c_str(), mitk::StringProperty::New(value)); + } + } + MITK_INFO << "...finished!" << std::endl; try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } result.push_back(image.GetPointer()); return result; } -bool mitk::ItkFileReaderService::CanRead(const std::string& path) const +bool mitk::ItkImageIO::CanRead(const std::string& path) const { if (AbstractFileReader::CanRead(path) == false) return false; itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(path.c_str(), itk::ImageIOFactory::ReadMode); if (imageIO.IsNull()) return false; return imageIO->CanReadFile(path.c_str()); } -mitk::ItkFileReaderService* mitk::ItkFileReaderService::Clone() const +void ItkImageIO::Write(const BaseData* data, const std::string& path) +{ + +} + +void ItkImageIO::Write(const BaseData* data, std::ostream& stream) +{ + AbstractFileWriter::Write(data, stream); +} + +ItkImageIO* ItkImageIO::Clone() const { - return new ItkFileReaderService(*this); + return new ItkImageIO(*this); +} + } diff --git a/Core/Code/Internal/mitkItkFileReaderService.h b/Core/Code/Internal/mitkItkImageIO.h similarity index 53% rename from Core/Code/Internal/mitkItkFileReaderService.h rename to Core/Code/Internal/mitkItkImageIO.h index 1bcca01e47..0b25600207 100644 --- a/Core/Code/Internal/mitkItkFileReaderService.h +++ b/Core/Code/Internal/mitkItkImageIO.h @@ -1,56 +1,64 @@ /*=================================================================== 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 MITKITKFILEREADERSERVICE_H -#define MITKITKFILEREADERSERVICE_H +#ifndef MITKITKFILEIO_H +#define MITKITKFILEIO_H -#include "mitkAbstractFileReader.h" +#include "mitkAbstractFileIO.h" + +#include namespace mitk { -// This class represents ITK image file reader instances -// registerred via the ITK object factory system as a micro -// service. -class ItkFileReaderService : public AbstractFileReader +// This class wraps ITK image IO objects registered via the +// ITK object factory system +class ItkImageIO : public AbstractFileIO { public: - ItkFileReaderService(const ItkFileReaderService& other); + ItkImageIO(itk::ImageIOBase::Pointer imageIO); - ItkFileReaderService(const std::vector& extensions, const std::string& category); - virtual ~ItkFileReaderService(); + // -------------- AbstractFileReader ------------- using AbstractFileReader::Read; virtual std::vector > Read(const std::string& path); virtual std::vector > Read(std::istream& stream); using AbstractFileReader::CanRead; virtual bool CanRead(const std::string& path) const; + // -------------- AbstractFileWriter ------------- + + virtual void Write(const BaseData* data, const std::string& path); + virtual void Write(const BaseData* data, std::ostream& stream); + private: - ItkFileReaderService* Clone() const; + ItkImageIO(const ItkImageIO& other); + + ItkImageIO* Clone() const; - us::ServiceRegistration m_ServiceReg; + std::vector FixUpImageIOExtensions(const std::string& imageIOName); + itk::ImageIOBase::Pointer m_ImageIO; }; } // namespace mitk -#endif /* MITKITKFILEREADERSERVICE_H */ +#endif /* MITKITKFILEIO_H */ diff --git a/Core/Code/Internal/mitkMimeTypeProvider.cpp b/Core/Code/Internal/mitkMimeTypeProvider.cpp index d535c1091d..b91841fda0 100644 --- a/Core/Code/Internal/mitkMimeTypeProvider.cpp +++ b/Core/Code/Internal/mitkMimeTypeProvider.cpp @@ -1,199 +1,200 @@ /*=================================================================== 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 #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) { } 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 (MapType::const_iterator iter = m_MimeTypeToRefs.begin(), end = m_MimeTypeToRefs.end(); iter != end; ++iter) { result.push_back(iter->first); } 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; std::vector > mimeTypeRefs; for (MapType::const_iterator iter = m_MimeTypeToRefs.begin(), end = m_MimeTypeToRefs.end(); iter != end; ++iter) { us::Any any = iter->second.rbegin()->GetProperty(IMimeType::PROP_EXTENSIONS()); if (!any.Empty() && any.Type() == typeid(std::vector)) { const std::vector& extensions = us::ref_any_cast >(any); if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end()) { mimeTypeRefs.push_back(*(iter->second.rbegin())); } } } std::sort(mimeTypeRefs.begin(), mimeTypeRefs.end()); for (std::vector >::reverse_iterator iter = mimeTypeRefs.rbegin(); iter != mimeTypeRefs.rend(); ++iter) { result.push_back(us::ref_any_cast(iter->GetProperty(IMimeType::PROP_ID()))); } return result; } std::vector MimeTypeProvider::GetMimeTypesForCategory(const std::string& category) const { std::vector result; for (MapType::const_iterator iter = m_MimeTypeToRefs.begin(), end = m_MimeTypeToRefs.end(); iter != end; ++iter) { us::Any cat = iter->second.rbegin()->GetProperty(IMimeType::PROP_CATEGORY()); if (!cat.Empty() && cat.Type() == typeid(std::string) && us::ref_any_cast(cat) == category) { result.push_back(iter->first); } } return result; } std::string MimeTypeProvider::GetDescription(const std::string& mimeType) const { MapType::const_iterator iter = m_MimeTypeToRefs.find(mimeType); if (iter == m_MimeTypeToRefs.end()) return std::string(); us::Any description = iter->second.rbegin()->GetProperty(IMimeType::PROP_DESCRIPTION()); if (!description.Empty() && description.Type() == typeid(std::string)) { return us::ref_any_cast(description); } return std::string(); } std::vector MimeTypeProvider::GetExtensions(const std::string& mimeType) const { MapType::const_iterator iter = m_MimeTypeToRefs.find(mimeType); if (iter == m_MimeTypeToRefs.end()) return std::vector(); us::Any extensions = iter->second.rbegin()->GetProperty(IMimeType::PROP_EXTENSIONS()); if (!extensions.Empty() && extensions.Type() == typeid(std::vector)) { return us::ref_any_cast >(extensions); } return std::vector(); } std::string MimeTypeProvider::GetCategory(const std::string& mimeType) const { MapType::const_iterator iter = m_MimeTypeToRefs.find(mimeType); if (iter == m_MimeTypeToRefs.end()) return std::string(); us::Any category = iter->second.rbegin()->GetProperty(IMimeType::PROP_CATEGORY()); if (!category.Empty() && category.Type() == typeid(std::string)) { return us::ref_any_cast(category); } return std::string(); } std::vector MimeTypeProvider::GetCategories() const { std::vector result; for (MapType::const_iterator iter = m_MimeTypeToRefs.begin(), end = m_MimeTypeToRefs.end(); iter != end; ++iter) { us::Any category = iter->second.rbegin()->GetProperty(IMimeType::PROP_CATEGORY()); if (!category.Empty() && category.Type() == typeid(std::string)) { std::string s = us::ref_any_cast(category); if (!s.empty()) { result.push_back(s); } } } + std::sort(result.begin(), result.end()); result.erase(std::unique(result.begin(), result.end()), result.end()); return result; } us::ServiceReference MimeTypeProvider::AddingService(const ServiceReferenceType& reference) { us::Any id = reference.GetProperty(IMimeType::PROP_ID()); if (!id.Empty() && id.Type() == typeid(std::string)) { m_MimeTypeToRefs[us::ref_any_cast(id)].insert(reference); return reference; } return ServiceReferenceType(); } void MimeTypeProvider::ModifiedService(const ServiceReferenceType& /*reference*/, ServiceReferenceType /*service*/) { } void MimeTypeProvider::RemovedService(const ServiceReferenceType& /*reference*/, ServiceReferenceType service) { std::string id = us::ref_any_cast(service.GetProperty(IMimeType::PROP_ID())); std::set& refs = m_MimeTypeToRefs[id]; refs.erase(service); if (refs.empty()) { m_MimeTypeToRefs.erase(id); } } } diff --git a/Core/Code/files.cmake b/Core/Code/files.cmake index 954af4eee9..d3ae8f12c3 100644 --- a/Core/Code/files.cmake +++ b/Core/Code/files.cmake @@ -1,409 +1,410 @@ set(H_FILES Algorithms/itkImportMitkImageContainer.h Algorithms/itkImportMitkImageContainer.txx Algorithms/itkMITKScalarImageToHistogramGenerator.h Algorithms/itkMITKScalarImageToHistogramGenerator.txx Algorithms/mitkInstantiateAccessFunctions.h Algorithms/mitkPixelTypeList.h Algorithms/mitkPPArithmeticDec.h Algorithms/mitkPPArgCount.h Algorithms/mitkPPCat.h Algorithms/mitkPPConfig.h Algorithms/mitkPPControlExprIIf.h Algorithms/mitkPPControlIf.h Algorithms/mitkPPControlIIf.h Algorithms/mitkPPDebugError.h Algorithms/mitkPPDetailAutoRec.h Algorithms/mitkPPDetailDMCAutoRec.h Algorithms/mitkPPExpand.h Algorithms/mitkPPFacilitiesEmpty.h Algorithms/mitkPPFacilitiesExpand.h Algorithms/mitkPPLogicalBool.h Algorithms/mitkPPRepetitionDetailDMCFor.h Algorithms/mitkPPRepetitionDetailEDGFor.h Algorithms/mitkPPRepetitionDetailFor.h Algorithms/mitkPPRepetitionDetailMSVCFor.h Algorithms/mitkPPRepetitionFor.h Algorithms/mitkPPSeqElem.h Algorithms/mitkPPSeqForEach.h Algorithms/mitkPPSeqForEachProduct.h Algorithms/mitkPPSeq.h Algorithms/mitkPPSeqEnum.h Algorithms/mitkPPSeqSize.h Algorithms/mitkPPSeqToTuple.h Algorithms/mitkPPStringize.h Algorithms/mitkPPTupleEat.h Algorithms/mitkPPTupleElem.h Algorithms/mitkPPTupleRem.h Algorithms/mitkClippedSurfaceBoundsCalculator.h Algorithms/mitkExtractSliceFilter.h Algorithms/mitkConvert2Dto3DImageFilter.h Algorithms/mitkPlaneClipping.h Common/mitkCommon.h Common/mitkExceptionMacro.h DataManagement/mitkProportionalTimeGeometry.h DataManagement/mitkTimeGeometry.h DataManagement/mitkImageAccessByItk.h DataManagement/mitkImageCast.h DataManagement/mitkImagePixelAccessor.h DataManagement/mitkImagePixelReadAccessor.h DataManagement/mitkImagePixelWriteAccessor.h DataManagement/mitkImageReadAccessor.h DataManagement/mitkImageWriteAccessor.h DataManagement/mitkITKImageImport.h DataManagement/mitkITKImageImport.txx DataManagement/mitkImageToItk.h DataManagement/mitkShaderProperty.h DataManagement/mitkImageToItk.txx DataManagement/mitkTimeSlicedGeometry.h # Deprecated, empty for compatibility reasons. DataManagement/mitkPropertyListReplacedObserver.cpp DataManagement/mitkVectorDeprecated.h DataManagement/mitkArray.h DataManagement/mitkQuaternion.h DataManagement/mitkNumericTypes.h DataManagement/mitkVector.h DataManagement/mitkPoint.h DataManagement/mitkMatrix.h Interactions/mitkEventMapperAddOn.h Interfaces/mitkIDataNodeReader.h Interfaces/mitkIFileWriter.h Interfaces/mitkIFileWriter.cpp Interfaces/mitkIFileReader.h Interfaces/mitkIFileReader.cpp Rendering/mitkLocalStorageHandler.h Rendering/Colortables/HotIron.h Rendering/Colortables/Jet.h Rendering/Colortables/PET20.h Rendering/Colortables/PETColor.h IO/mitkPixelTypeTraits.h ) set(CPP_FILES Algorithms/mitkBaseDataSource.cpp Algorithms/mitkCompareImageDataFilter.cpp Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkPlaneGeometryDataToSurfaceFilter.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToImageFilter.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkFocusManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkSlicesRotator.cpp Controllers/mitkSlicesSwiveller.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkInteractorCameraController.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseGeometry.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataStorage.cpp # DataManagement/mitkDataTree.cpp DataManagement/mitkDataNode.cpp # DataManagement/mitkDataTreeStorage.cpp DataManagement/mitkDisplayGeometry.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkPlaneGeometryData.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTableProperty.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModeOperation.cpp DataManagement/mitkModifiedLock.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkPropertyObserver.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkApplyTransformMatrixOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStateTransitionOperation.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkVector.cpp DataManagement/mitkNumericConstants.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkMaterial.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilters.cpp DataManagement/mitkShaderProperty.cpp Interactions/mitkAction.cpp Interactions/mitkAffineInteractor.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCoordinateSupplier.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkDisplayPositionEvent.cpp # Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded # Interactions/mitkDisplayVectorInteractorScroll.cpp Interactions/mitkEvent.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventDescription.cpp Interactions/mitkEventFactory.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkEventMapper.cpp Interactions/mitkEventRecorder.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkGlobalInteraction.cpp Interactions/mitkInteractor.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMovePointSetInteractor.cpp Interactions/mitkMoveBaseDataInteractor.cpp Interactions/mitkNodeDepententPointSetInteractor.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkPointSetInteractor.cpp Interactions/mitkPositionEvent.cpp Interactions/mitkPositionTracker.cpp Interactions/mitkSinglePointDataInteractor.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkState.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateEvent.cpp Interactions/mitkStateMachine.cpp Interactions/mitkStateMachineFactory.cpp Interactions/mitkTransition.cpp Interactions/mitkWheelEvent.cpp Interactions/mitkKeyEvent.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkCrosshairPositionEvent.cpp Interactions/mitkXML2EventParser.cpp Interfaces/mitkIMimeType.cpp Interfaces/mitkIMimeTypeProvider.cpp Interfaces/mitkInteractionEventObserver.cpp Interfaces/mitkIShaderRepository.cpp Interfaces/mitkIPropertyAliases.cpp Interfaces/mitkIPropertyDescriptions.cpp Interfaces/mitkIPropertyExtensions.cpp Interfaces/mitkIPropertyFilters.cpp Interfaces/mitkIPersistenceService.cpp IO/mitkAbstractFileReader.cpp IO/mitkAbstractFileWriter.cpp + IO/mitkAbstractFileIO.cpp IO/mitkDicomSeriesReader.cpp IO/mitkDicomSR_LoadDICOMScalar.cpp IO/mitkDicomSR_LoadDICOMScalar4D.cpp IO/mitkDicomSR_LoadDICOMRGBPixel.cpp IO/mitkDicomSR_LoadDICOMRGBPixel4D.cpp IO/mitkDicomSR_ImageBlockDescriptor.cpp IO/mitkDicomSR_GantryTiltInformation.cpp IO/mitkDicomSR_SliceGroupingResult.cpp IO/mitkFileReader.cpp IO/mitkFileWriter.cpp IO/mitkFileReaderRegistry.cpp IO/mitkFileWriterRegistry.cpp # IO/mitkIpPicGet.c IO/mitkImageGenerator.cpp IO/mitkIOConstants.cpp IO/mitkIOUtil.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkOperation.cpp # IO/mitkPicFileIOFactory.cpp # IO/mitkPicFileReader.cpp # IO/mitkPicFileWriter.cpp # IO/mitkPicHelper.cpp # IO/mitkPicVolumeTimeSeriesIOFactory.cpp # IO/mitkPicVolumeTimeSeriesReader.cpp IO/mitkPixelType.cpp IO/mitkSimpleMimeType.cpp IO/mitkStandardFileLocations.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkLog.cpp Rendering/mitkBaseRenderer.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkRenderWindowFrame.cpp Rendering/mitkPlaneGeometryDataMapper2D.cpp Rendering/mitkPlaneGeometryDataVtkMapper3D.cpp Rendering/mitkGLMapper.cpp Rendering/mitkGradientBackground.cpp Rendering/mitkManufacturerLogo.cpp Rendering/mitkMapper.cpp Rendering/mitkPointSetGLMapper2D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkSurfaceGLMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVolumeDataVtkMapper3D.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp Rendering/mitkOverlay.cpp Rendering/mitkVtkOverlay.cpp Rendering/mitkVtkOverlay2D.cpp Rendering/mitkVtkOverlay3D.cpp Rendering/mitkOverlayManager.cpp Rendering/mitkAbstractOverlayLayouter.cpp Rendering/mitkTextOverlay2D.cpp Rendering/mitkTextOverlay3D.cpp Rendering/mitkLabelOverlay3D.cpp Rendering/mitkOverlay2DLayouter.cpp Rendering/mitkScaleLegendOverlay Common/mitkException.cpp Common/mitkCommon.h Common/mitkCoreObjectFactoryBase.cpp Common/mitkCoreObjectFactory.cpp Common/mitkCoreServices.cpp Internal/mitkCoreActivator.cpp Internal/mitkFileReaderWriterBase.cpp - Internal/mitkItkFileReaderService.cpp + Internal/mitkItkImageIO.cpp Internal/mitkLegacyFileReaderService.cpp #Internal/mitkLegacyFileWriterService.cpp Internal/mitkMimeTypeProvider.cpp Internal/mitkPointSetReaderService.cpp Internal/mitkPointSetWriterService.cpp Internal/mitkRawImageFileReader.cpp ) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml mitkLevelWindowPresets.xml ) diff --git a/Modules/QtWidgets/QmitkIOUtil.cpp b/Modules/QtWidgets/QmitkIOUtil.cpp index 16626b1934..d704106635 100644 --- a/Modules/QtWidgets/QmitkIOUtil.cpp +++ b/Modules/QtWidgets/QmitkIOUtil.cpp @@ -1,546 +1,545 @@ /*=================================================================== 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 "QmitkIOUtil.h" #include #include #include #include "mitkCoreServices.h" #include "mitkIMimeTypeProvider.h" #include "mitkFileReaderRegistry.h" #include "mitkFileWriterRegistry.h" #include "QmitkFileReaderOptionsDialog.h" #include "QmitkFileWriterOptionsDialog.h" // QT #include #include #include //ITK #include struct QmitkIOUtil::Impl { struct ReaderOptionsDialogFunctor : public ReaderOptionsFunctorBase { virtual bool operator()(const std::string& path, const std::vector& readerLabels, const std::vector& readers, mitk::IFileReader*& selectedReader) { QStringList qLabels; for (std::vector::const_iterator iter = readerLabels.begin(), iterEnd = readerLabels.end(); iter != iterEnd; ++iter) { qLabels.push_back(QString::fromStdString(*iter)); } QList qReaders; for (std::vector::const_iterator iter = readers.begin(), iterEnd = readers.end(); iter != iterEnd; ++iter) { qReaders.push_back(*iter); } QmitkFileReaderOptionsDialog dialog(QString::fromStdString(path), qLabels, qReaders); if (dialog.exec() == QDialog::Accepted) { selectedReader = dialog.GetReader(); return !dialog.ReuseOptions(); } else { selectedReader = NULL; return true; } } }; struct WriterOptionsDialogFunctor : public WriterOptionsFunctorBase { virtual bool operator()(const std::string& path, const std::vector& writerLabels, const std::vector& writers, mitk::IFileWriter*& selectedWriter) { QStringList qLabels; for (std::vector::const_iterator iter = writerLabels.begin(), iterEnd = writerLabels.end(); iter != iterEnd; ++iter) { qLabels.push_back(QString::fromStdString(*iter)); } QList qWriters; for (std::vector::const_iterator iter = writers.begin(), iterEnd = writers.end(); iter != iterEnd; ++iter) { qWriters.push_back(*iter); } QmitkFileWriterOptionsDialog dialog(QString::fromStdString(path), qLabels, qWriters); if (dialog.exec() == QDialog::Accepted) { selectedWriter = dialog.GetWriter(); return !dialog.ReuseOptions(); } else { selectedWriter = NULL; return true; } } }; }; QString QmitkIOUtil::GetFileOpenFilterString() { QString filters; mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); std::vector categories = mimeTypeProvider->GetCategories(); - std::sort(categories.begin(), categories.end()); for (std::vector::iterator cat = categories.begin(); cat != categories.end(); ++cat) { QSet filterExtensions; std::vector mimeTypes = mimeTypeProvider->GetMimeTypesForCategory(*cat); for (std::vector::iterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt) { std::vector extensions = mimeTypeProvider->GetExtensions(*mt); for (std::vector::iterator ext = extensions.begin(); ext != extensions.end(); ++ext) { filterExtensions << QString::fromStdString(*ext); } } QString filter = QString::fromStdString(*cat) + " ("; foreach(const QString& extension, filterExtensions) { filter += "*." + extension + " "; } filter = filter.replace(filter.size()-1, 1, ')'); filters += ";;" + filter; } filters.prepend("All (*.*)"); return filters; } QmitkIOUtil::SaveFilter QmitkIOUtil::GetFileSaveFilter(const mitk::BaseData* baseData) { return SaveFilter(baseData); } QmitkIOUtil::SaveFilter QmitkIOUtil::GetFileSaveFilter(const std::string& baseDataType) { return SaveFilter(baseDataType); } QList QmitkIOUtil::Load(const QStringList& paths, QWidget* parent) { std::vector qPaths; foreach(const QString& file, paths) { qPaths.push_back(file.toStdString()); } std::vector result; Impl::ReaderOptionsDialogFunctor optionsCallback; std::string errMsg = Load(qPaths, &result, NULL, NULL, &optionsCallback); if (!errMsg.empty()) { QMessageBox::warning(parent, "Error reading files", QString::fromStdString(errMsg)); mitkThrow() << errMsg; } QList qResult; for(std::vector::const_iterator iter = result.begin(), iterEnd = result.end(); iter != iterEnd; ++iter) { qResult << *iter; } return qResult; } mitk::DataStorage::SetOfObjects::Pointer QmitkIOUtil::Load(const QStringList& paths, mitk::DataStorage& storage, QWidget* parent) { std::vector qPaths; foreach(const QString& file, paths) { qPaths.push_back(file.toStdString()); } mitk::DataStorage::SetOfObjects::Pointer nodeResult = mitk::DataStorage::SetOfObjects::New(); Impl::ReaderOptionsDialogFunctor optionsCallback; std::string errMsg = Load(qPaths, NULL, nodeResult, &storage, &optionsCallback); if (!errMsg.empty()) { QMessageBox::warning(parent, "Error reading files", QString::fromStdString(errMsg)); mitkThrow() << errMsg; } return nodeResult; } QList QmitkIOUtil::Load(const QString& path, QWidget* parent) { QStringList paths; paths << path; return Load(paths, parent); } mitk::DataStorage::SetOfObjects::Pointer QmitkIOUtil::Load(const QString& path, mitk::DataStorage& storage, QWidget* parent) { QStringList paths; paths << path; return Load(paths, storage, parent); } QString QmitkIOUtil::Save(const mitk::BaseData* data, const QString& defaultBaseName, const QString& defaultPath, QWidget* parent) { std::vector dataVector; dataVector.push_back(data); QStringList defaultBaseNames; defaultBaseNames.push_back(defaultBaseName); return Save(dataVector, defaultBaseNames, defaultPath, parent).back(); } QStringList QmitkIOUtil::Save(const std::vector& data, const QStringList& defaultBaseNames, const QString& defaultPath, QWidget* parent) { QStringList fileNames; QString currentPath = defaultPath; std::vector saveInfos; int counter = 0; for(std::vector::const_iterator dataIter = data.begin(), dataIterEnd = data.end(); dataIter != dataIterEnd; ++dataIter, ++counter) { SaveFilter filters(*dataIter); // If there is only the "__all__" filter string, it means there is no writer for this base data if (filters.Size() < 2) { QMessageBox::warning(parent, "Saving not possible", QString("No writer available for type \"%1\"").arg( QString::fromStdString((*dataIter)->GetNameOfClass()))); continue; } // Construct a default path and file name QString filterString = filters.ToString(); QString selectedFilter = filters.GetDefaultFilter(); QString fileName = currentPath; QString dialogTitle = "Save " + QString::fromStdString((*dataIter)->GetNameOfClass()); if (counter < defaultBaseNames.size()) { dialogTitle += " \"" + defaultBaseNames[counter] + "\""; fileName += QDir::separator() + defaultBaseNames[counter]; std::pair defaultExt = mitk::FileWriterRegistry::GetDefaultExtension(*dataIter); if (!defaultExt.first.empty()) { fileName += "." + QString::fromStdString(defaultExt.first); QString filter = filters.GetFilterForMimeType(defaultExt.second); if (!filter.isEmpty()) { selectedFilter = filter; } } } // Ask the user for a file name QString nextName = QFileDialog::getSaveFileName(parent, dialogTitle, fileName, filterString, &selectedFilter); if (nextName.isEmpty()) { continue; } fileName = nextName; QFileInfo fileInfo(fileName); currentPath = fileInfo.absolutePath(); QString suffix = fileInfo.completeSuffix(); std::string mimeType = filters.GetMimeTypeForFilter(selectedFilter); mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); // If the filename contains a suffix, use it but check if it is valid if (!suffix.isEmpty()) { std::vector availableTypes = mimeTypeProvider->GetMimeTypesForExtension(suffix.toStdString()); // Check if the selected mime-type is related to the specified suffix (file extension). // If not, get the best matching mime-type for the suffix. if (std::find(availableTypes.begin(), availableTypes.end(), mimeType) == availableTypes.end()) { mimeType.clear(); for (std::vector::const_iterator availIter = availableTypes.begin(), availIterEnd = availableTypes.end(); availIter != availIterEnd; ++availIter) { if (filters.ContainsMimeType(*availIter)) { mimeType = *availIter; break; } } } if (mimeType.empty()) { // The extension is not valid (no mime-type found), bail out QMessageBox::warning(parent, "Saving not possible", QString("Extension \"%1\" unknown for type \"%2\"") .arg(suffix) .arg(QString::fromStdString((*dataIter)->GetNameOfClass()))); continue; } } else { // Create a default suffix, unless the file already exists and the user // already confirmed to overwrite it (without using a suffix) if (mimeType == SaveFilter::ALL_MIMETYPE) { // Use the highest ranked mime-type from the list mimeType = filters.GetDefaultMimeType(); } if (!fileInfo.exists()) { suffix = QString::fromStdString( mimeTypeProvider->GetExtensions(mimeType).front()); fileName += "." + suffix; // We changed the file name (added a suffix) so ask in case // the file aready exists. fileInfo = QFileInfo(fileName); if (fileInfo.exists()) { if (!fileInfo.isFile()) { QMessageBox::warning(parent, "Saving not possible", QString("The path \"%1\" is not a file").arg(fileName)); continue; } if (fileInfo.exists()) { if (QMessageBox::question(parent, "Replace File", "A file named \"%1\" already exists. Do you want to replace it?") == QMessageBox::No) { continue; } } } } } if (!QFileInfo(fileInfo.absolutePath()).isWritable()) { QMessageBox::warning(parent, "Saving not possible", QString("The path \"%1\" is not writable").arg(fileName)); continue; } fileNames.push_back(fileName); saveInfos.push_back(SaveInfo(*dataIter, mimeType, fileName.toStdString())); MITK_INFO << "****** SAVING TO FILENAME: " << fileName.toStdString(); } Impl::WriterOptionsDialogFunctor optionsCallback; std::string errMsg = Save(saveInfos, &optionsCallback); if (!errMsg.empty()) { QMessageBox::warning(parent, "Error writing files", QString::fromStdString(errMsg)); mitkThrow() << errMsg; } return fileNames; } void QmitkIOUtil::SaveBaseDataWithDialog(mitk::BaseData* data, std::string fileName, QWidget* /*parent*/) { Save(data, fileName); } void QmitkIOUtil::SaveSurfaceWithDialog(mitk::Surface::Pointer surface, std::string fileName, QWidget* /*parent*/) { Save(surface, fileName); } void QmitkIOUtil::SaveImageWithDialog(mitk::Image::Pointer image, std::string fileName, QWidget* /*parent*/) { Save(image, fileName); } void QmitkIOUtil::SavePointSetWithDialog(mitk::PointSet::Pointer pointset, std::string fileName, QWidget* /*parent*/) { Save(pointset, fileName); } struct QmitkIOUtil::SaveFilter::Impl { void Init(const std::string& baseDataType) { // Add an artifical filter for "All" m_MimeTypes.push_back(ALL_MIMETYPE); m_FilterStrings.push_back("All (*.*)"); // Get all writers and their mime types for the given base data type std::vector mimeTypes; std::vector refs = mitk::FileWriterRegistry::GetReferences(baseDataType); for (std::vector::const_iterator iter = refs.begin(), iterEnd = refs.end(); iter != iterEnd; ++iter) { std::string mimeType = iter->GetProperty(mitk::IFileWriter::PROP_MIMETYPE()).ToString(); if (!mimeType.empty() && std::find(mimeTypes.begin(), mimeTypes.end(), mimeType) == mimeTypes.end()) { mimeTypes.push_back(mimeType); } } mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); for (std::vector::const_iterator iter = mimeTypes.begin(), iterEnd = mimeTypes.end(); iter != iterEnd; ++iter) { QSet filterExtensions; std::vector extensions = mimeTypeProvider->GetExtensions(*iter); for (std::vector::iterator extIter = extensions.begin(), extIterEnd = extensions.end(); extIter != extIterEnd; ++extIter) { filterExtensions << QString::fromStdString(*extIter); } QString filter = QString::fromStdString(mimeTypeProvider->GetDescription(*iter)) + " ("; foreach(const QString& extension, filterExtensions) { filter += "*." + extension + " "; } filter = filter.replace(filter.size()-1, 1, ')'); m_MimeTypes.push_back(*iter); m_FilterStrings.push_back(filter); } } std::vector m_MimeTypes; QStringList m_FilterStrings; }; std::string QmitkIOUtil::SaveFilter::ALL_MIMETYPE = "__all__"; QmitkIOUtil::SaveFilter::SaveFilter(const QmitkIOUtil::SaveFilter& other) : d(new Impl(*other.d)) { } QmitkIOUtil::SaveFilter::SaveFilter(const std::string& baseDataType) : d(new Impl) { if (!baseDataType.empty()) { d->Init(baseDataType); } } QmitkIOUtil::SaveFilter::SaveFilter(const mitk::BaseData* baseData) : d(new Impl) { if (baseData != NULL) { d->Init(baseData->GetNameOfClass()); } } QmitkIOUtil::SaveFilter& QmitkIOUtil::SaveFilter::operator=(const QmitkIOUtil::SaveFilter& other) { d.reset(new Impl(*other.d)); return *this; } QString QmitkIOUtil::SaveFilter::GetFilterForMimeType(const std::string& mimeType) const { std::vector::const_iterator iter = std::find(d->m_MimeTypes.begin(), d->m_MimeTypes.end(), mimeType); if (iter == d->m_MimeTypes.end()) { return QString(); } int index = static_cast(iter - d->m_MimeTypes.begin()); if (index < 0 || index >= d->m_FilterStrings.size()) { return QString(); } return d->m_FilterStrings[index]; } std::string QmitkIOUtil::SaveFilter::GetMimeTypeForFilter(const QString& filter) const { int index = d->m_FilterStrings.indexOf(filter); if (index < 0) { return std::string(); } return d->m_MimeTypes[index]; } QString QmitkIOUtil::SaveFilter::GetDefaultFilter() const { if (d->m_FilterStrings.size() > 1) { return d->m_FilterStrings.at(1); } else if (d->m_FilterStrings.size() > 0) { return d->m_FilterStrings.front(); } return QString(); } std::string QmitkIOUtil::SaveFilter::GetDefaultMimeType() const { if (d->m_MimeTypes.size() > 1) { return d->m_MimeTypes.at(1); } else if (d->m_MimeTypes.size() > 0) { return d->m_MimeTypes.front(); } return std::string(); } QString QmitkIOUtil::SaveFilter::ToString() const { return d->m_FilterStrings.join(";;"); } int QmitkIOUtil::SaveFilter::Size() const { return d->m_FilterStrings.size(); } bool QmitkIOUtil::SaveFilter::IsEmpty() const { return d->m_FilterStrings.isEmpty(); } bool QmitkIOUtil::SaveFilter::ContainsMimeType(const std::string& mimeType) { return std::find(d->m_MimeTypes.begin(), d->m_MimeTypes.end(), mimeType) != d->m_MimeTypes.end(); }