diff --git a/Core/Code/Common/mitkCoreObjectFactory.cpp b/Core/Code/Common/mitkCoreObjectFactory.cpp index d4fce9c4a7..17c3d5e9c1 100644 --- a/Core/Code/Common/mitkCoreObjectFactory.cpp +++ b/Core/Code/Common/mitkCoreObjectFactory.cpp @@ -1,466 +1,412 @@ /*=================================================================== 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 "mitkConfig.h" #include "mitkCoreObjectFactory.h" #include "mitkAffineInteractor.h" #include "mitkColorProperty.h" #include "mitkDataNode.h" #include "mitkEnumerationProperty.h" #include "mitkPlaneGeometryData.h" #include "mitkPlaneGeometryDataMapper2D.h" #include "mitkPlaneGeometryDataVtkMapper3D.h" #include "mitkGeometry3D.h" #include "mitkGeometryData.h" #include "mitkImage.h" #include #include "mitkLevelWindowProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkPlaneGeometry.h" #include "mitkPointSet.h" #include "mitkPointSetVtkMapper2D.h" #include "mitkPointSetVtkMapper3D.h" #include "mitkProperties.h" #include "mitkPropertyList.h" #include "mitkSlicedGeometry3D.h" #include "mitkSmartPointerProperty.h" #include "mitkStringProperty.h" #include "mitkSurface.h" #include "mitkSurface.h" #include "mitkSurfaceGLMapper2D.h" #include "mitkSurfaceVtkMapper3D.h" #include "mitkTimeGeometry.h" #include "mitkTransferFunctionProperty.h" #include "mitkVolumeDataVtkMapper3D.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkRepresentationProperty.h" #include "mitkVtkResliceInterpolationProperty.h" // Legacy Support: #include -#include -#include -#include #include #include void mitk::CoreObjectFactory::RegisterExtraFactory(CoreObjectFactoryBase* factory) { MITK_DEBUG << "CoreObjectFactory: registering extra factory of type " << factory->GetNameOfClass(); m_ExtraFactories.insert(CoreObjectFactoryBase::Pointer(factory)); // Register Legacy Reader and Writer this->RegisterLegacyReaders(factory); this->RegisterLegacyWriters(factory); } void mitk::CoreObjectFactory::UnRegisterExtraFactory(CoreObjectFactoryBase *factory) { MITK_DEBUG << "CoreObjectFactory: un-registering extra factory of type " << factory->GetNameOfClass(); try { m_ExtraFactories.erase(factory); } catch( std::exception const& e) { MITK_ERROR << "Caugt exception while unregistering: " << e.what(); } } mitk::CoreObjectFactory::Pointer mitk::CoreObjectFactory::GetInstance() { static mitk::CoreObjectFactory::Pointer instance; if (instance.IsNull()) { instance = mitk::CoreObjectFactory::New(); } return instance; } mitk::CoreObjectFactory::~CoreObjectFactory() { for (std::list< mitk::LegacyFileReaderService* >::iterator it = m_LegacyReaders.begin(); it != m_LegacyReaders.end(); ++it) { delete *it; } for (std::list< mitk::LegacyFileWriterService* >::iterator it = m_LegacyWriters.begin(); it != m_LegacyWriters.end(); ++it) { delete *it; } } void mitk::CoreObjectFactory::SetDefaultProperties(mitk::DataNode* node) { if(node==NULL) return; mitk::DataNode::Pointer nodePointer = node; mitk::Image::Pointer image = dynamic_cast(node->GetData()); if(image.IsNotNull() && image->IsInitialized()) { mitk::ImageVtkMapper2D::SetDefaultProperties(node); mitk::VolumeDataVtkMapper3D::SetDefaultProperties(node); } mitk::Surface::Pointer surface = dynamic_cast(node->GetData()); if(surface.IsNotNull()) { mitk::SurfaceGLMapper2D::SetDefaultProperties(node); mitk::SurfaceVtkMapper3D::SetDefaultProperties(node); } mitk::PointSet::Pointer pointSet = dynamic_cast(node->GetData()); if(pointSet.IsNotNull()) { mitk::PointSetVtkMapper2D::SetDefaultProperties(node); mitk::PointSetVtkMapper3D::SetDefaultProperties(node); } for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { (*it)->SetDefaultProperties(node); } } mitk::CoreObjectFactory::CoreObjectFactory() { static bool alreadyDone = false; if (!alreadyDone) { CreateFileExtensionsMap(); - RegisterLegacyReaders(this); - RegisterLegacyWriters(this); + //RegisterLegacyReaders(this); + //RegisterLegacyWriters(this); alreadyDone = true; } } mitk::Mapper::Pointer mitk::CoreObjectFactory::CreateMapper(mitk::DataNode* node, MapperSlotId id) { mitk::Mapper::Pointer newMapper = NULL; mitk::Mapper::Pointer tmpMapper = NULL; // check whether extra factories provide mapper for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { tmpMapper = (*it)->CreateMapper(node,id); if(tmpMapper.IsNotNull()) newMapper = tmpMapper; } if (newMapper.IsNull()) { mitk::BaseData *data = node->GetData(); if ( id == mitk::BaseRenderer::Standard2D ) { if((dynamic_cast(data)!=NULL)) { newMapper = mitk::ImageVtkMapper2D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::PlaneGeometryDataMapper2D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::SurfaceGLMapper2D::New(); // cast because SetDataNode is not virtual mitk::SurfaceGLMapper2D *castedMapper = dynamic_cast(newMapper.GetPointer()); castedMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::PointSetVtkMapper2D::New(); newMapper->SetDataNode(node); } } else if ( id == mitk::BaseRenderer::Standard3D ) { if((dynamic_cast(data) != NULL)) { newMapper = mitk::VolumeDataVtkMapper3D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::PlaneGeometryDataVtkMapper3D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::SurfaceVtkMapper3D::New(); newMapper->SetDataNode(node); } else if((dynamic_cast(data)!=NULL)) { newMapper = mitk::PointSetVtkMapper3D::New(); newMapper->SetDataNode(node); } } } return newMapper; } const char* mitk::CoreObjectFactory::GetFileExtensions() { MultimapType aMap; for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { aMap = (*it)->GetFileExtensionsMap(); this->MergeFileExtensions(m_FileExtensionsMap, aMap); } this->CreateFileExtensions(m_FileExtensionsMap, m_FileExtensions); return m_FileExtensions.c_str(); } void mitk::CoreObjectFactory::MergeFileExtensions(MultimapType& fileExtensionsMap, MultimapType inputMap) { bool duplicateFound = false; std::pair pairOfIter; for (MultimapType::iterator it = inputMap.begin(); it != inputMap.end(); ++it) { duplicateFound = false; pairOfIter = fileExtensionsMap.equal_range((*it).first); for (MultimapType::iterator it2 = pairOfIter.first; it2 != pairOfIter.second; ++it2) { //cout << " [" << (*it).first << ", " << (*it).second << "]" << endl; std::string aString = (*it2).second; if (aString.compare((*it).second) == 0) { //cout << " DUP!! [" << (*it).first << ", " << (*it).second << "]" << endl; duplicateFound = true; break; } } if (!duplicateFound) { fileExtensionsMap.insert(std::pair((*it).first, (*it).second)); } } } mitk::CoreObjectFactoryBase::MultimapType mitk::CoreObjectFactory::GetFileExtensionsMap() { return m_FileExtensionsMap; } void mitk::CoreObjectFactory::CreateFileExtensionsMap() { + /* m_FileExtensionsMap.insert(std::pair("*.dcm", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.DCM", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.dc3", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.DC3", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.gdcm", "DICOM files")); m_FileExtensionsMap.insert(std::pair("*.seq", "DKFZ Pic")); - m_FileExtensionsMap.insert(std::pair("*.pic", "DKFZ Pic")); - m_FileExtensionsMap.insert(std::pair("*.pic.gz", "DKFZ Pic")); - m_FileExtensionsMap.insert(std::pair("*.mhd", "MetaImage")); m_FileExtensionsMap.insert(std::pair("*.seq.gz", "DKFZ Pic")); - m_FileExtensionsMap.insert(std::pair("*.hdr", "Analyze Format")); - m_FileExtensionsMap.insert(std::pair("*.img", "Analyze Format")); - m_FileExtensionsMap.insert(std::pair("*.img.gz", "Analyze Format")); - m_FileExtensionsMap.insert(std::pair("*.nrrd", "Nearly Raw Raster Data")); - m_FileExtensionsMap.insert(std::pair("*.nhdr", "NRRD with detached header")); - m_FileExtensionsMap.insert(std::pair("*.mps", "Point sets")); - m_FileExtensionsMap.insert(std::pair("*.pic", "Sets of 2D slices")); - m_FileExtensionsMap.insert(std::pair("*.pic.gz", "Sets of 2D slices")); - m_FileExtensionsMap.insert(std::pair("*.bmp", "Sets of 2D slices")); - m_FileExtensionsMap.insert(std::pair("*.png", "Sets of 2D slices")); - m_FileExtensionsMap.insert(std::pair("*.jpg", "Sets of 2D slices")); - m_FileExtensionsMap.insert(std::pair("*.jpeg", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.dcm", "Sets of 2D slices")); m_FileExtensionsMap.insert(std::pair("*.gdcm", "Sets of 2D slices")); - m_FileExtensionsMap.insert(std::pair("*.ima", "Sets of 2D slices")); - m_FileExtensionsMap.insert(std::pair("*.tiff", "Sets of 2D slices")); - m_FileExtensionsMap.insert(std::pair("*.tif", "Sets of 2D slices")); - m_FileExtensionsMap.insert(std::pair("*.stl", "Surface files")); - m_FileExtensionsMap.insert(std::pair("*.vtk", "Surface files")); - m_FileExtensionsMap.insert(std::pair("*.vtp", "Surface files")); - m_FileExtensionsMap.insert(std::pair("*.obj", "Surface files")); - m_FileExtensionsMap.insert(std::pair("*.nii", "NIfTI format")); - m_FileExtensionsMap.insert(std::pair("*.nii.gz", "NIfTI format")); - m_FileExtensionsMap.insert(std::pair("*.gipl", "UMDS GIPL Format Files")); - m_FileExtensionsMap.insert(std::pair("*.gipl.gz", "UMDS GIPL Format Files")); - - //m_SaveFileExtensionsMap.insert(std::pair("*.pic", "DKFZ Pic")); - m_SaveFileExtensionsMap.insert(std::pair("*.mhd", "MetaImage")); - m_SaveFileExtensionsMap.insert(std::pair("*.vtk", "Surface Files")); - m_SaveFileExtensionsMap.insert(std::pair("*.vti", "VTK Image Data Files")); - m_SaveFileExtensionsMap.insert(std::pair("*.hdr", "Analyze Format")); - m_SaveFileExtensionsMap.insert(std::pair("*.png", "Sets of 2D slices")); - m_SaveFileExtensionsMap.insert(std::pair("*.tiff", "Sets of 2D slices")); - m_SaveFileExtensionsMap.insert(std::pair("*.tif", "Sets of 2D slices")); - m_SaveFileExtensionsMap.insert(std::pair("*.jpg", "Sets of 2D slices")); - m_SaveFileExtensionsMap.insert(std::pair("*.jpeg", "Sets of 2D slices")); - m_SaveFileExtensionsMap.insert(std::pair("*.bmp", "Sets of 2D slices")); - m_SaveFileExtensionsMap.insert(std::pair("*.dcm", "Sets of 2D slices")); - m_SaveFileExtensionsMap.insert(std::pair("*.gipl", "UMDS GIPL Format Files")); - m_SaveFileExtensionsMap.insert(std::pair("*.gipl.gz", "UMDS compressed GIPL Format Files")); - m_SaveFileExtensionsMap.insert(std::pair("*.nii", "NIfTI format")); - m_SaveFileExtensionsMap.insert(std::pair("*.nii.gz", "NIfTI compressed format")); - m_SaveFileExtensionsMap.insert(std::pair("*.nrrd", "Nearly Raw Raster Data")); - m_SaveFileExtensionsMap.insert(std::pair("*.nhdr", "NRRD with detached header")); - m_SaveFileExtensionsMap.insert(std::pair("*.lsm", "Microscope Images")); - m_SaveFileExtensionsMap.insert(std::pair("*.dwi", "Diffusion Weighted Images")); - m_SaveFileExtensionsMap.insert(std::pair("*.hdwi", "Diffusion Weighted Images")); - m_SaveFileExtensionsMap.insert(std::pair("*.qbi", "Q-Ball Images")); - m_SaveFileExtensionsMap.insert(std::pair("*.hqbi", "Q-Ball Images")); - + */ } const char* mitk::CoreObjectFactory::GetSaveFileExtensions() { MultimapType aMap; for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end() ; it++ ) { aMap = (*it)->GetSaveFileExtensionsMap(); this->MergeFileExtensions(m_SaveFileExtensionsMap, aMap); } this->CreateFileExtensions(m_SaveFileExtensionsMap, m_SaveFileExtensions); return m_SaveFileExtensions.c_str(); } mitk::CoreObjectFactoryBase::MultimapType mitk::CoreObjectFactory::GetSaveFileExtensionsMap() { return m_SaveFileExtensionsMap; } mitk::CoreObjectFactory::FileWriterList mitk::CoreObjectFactory::GetFileWriters() { FileWriterList allWriters = m_FileWriters; //sort to merge lists later on typedef std::set FileWriterSet; FileWriterSet fileWritersSet; fileWritersSet.insert(allWriters.begin(), allWriters.end()); //collect all extra factories for (ExtraFactoriesContainer::iterator it = m_ExtraFactories.begin(); it != m_ExtraFactories.end(); it++ ) { FileWriterList list2 = (*it)->GetFileWriters(); //add them to the sorted set fileWritersSet.insert(list2.begin(), list2.end()); } //write back to allWriters to return a list allWriters.clear(); allWriters.insert(allWriters.end(), fileWritersSet.begin(), fileWritersSet.end()); return allWriters; } void mitk::CoreObjectFactory::MapEvent(const mitk::Event*, const int) { } std::string mitk::CoreObjectFactory::GetDescriptionForExtension(const std::string& extension) { std::multimap fileExtensionMap = GetSaveFileExtensionsMap(); for(std::multimap::iterator it = fileExtensionMap.begin(); it != fileExtensionMap.end(); it++) if (it->first == extension) return it->second; return ""; // If no matching extension was found, return emtpy string } void mitk::CoreObjectFactory::RegisterLegacyReaders(mitk::CoreObjectFactoryBase* factory) { // We are not really interested in the string, just call the method since // many readers initialize the map the first time when this method is called factory->GetFileExtensions(); std::map > extensionsByCategories; std::multimap fileExtensionMap = factory->GetFileExtensionsMap(); for(std::multimap::iterator it = fileExtensionMap.begin(); it != fileExtensionMap.end(); it++) { std::string extension = it->first; // remove "*." extension = extension.erase(0,2); extensionsByCategories[it->second].push_back(extension); } for(std::map >::iterator iter = extensionsByCategories.begin(), endIter = extensionsByCategories.end(); iter != endIter; ++iter) { m_LegacyReaders.push_back(new mitk::LegacyFileReaderService(iter->second, iter->first)); } } void mitk::CoreObjectFactory::RegisterLegacyWriters(mitk::CoreObjectFactoryBase* factory) { // Get all external Writers mitk::CoreObjectFactory::FileWriterList writers = factory->GetFileWriters(); // We are not really interested in the string, just call the method since // many writers initialize the map the first time when this method is called factory->GetSaveFileExtensions(); MultimapType fileExtensionMap = factory->GetSaveFileExtensionsMap(); for(mitk::CoreObjectFactory::FileWriterList::iterator it = writers.begin(); it != writers.end(); it++) { std::vector extensions = (*it)->GetPossibleFileExtensions(); if (extensions.empty()) continue; std::string description; for(std::vector::iterator ext = extensions.begin(); ext != extensions.end(); ext++) { if (ext->empty()) continue; std::string extension = *ext; std::string extensionWithStar = extension; if (extension.find_first_of('*') == 0) { // remove "*." extension = extension.substr(0, extension.size()-2); } else { extensionWithStar.insert(extensionWithStar.begin(), '*'); } for(MultimapType::iterator fileExtensionIter = fileExtensionMap.begin(); fileExtensionIter != fileExtensionMap.end(); fileExtensionIter++) { if (fileExtensionIter->first == extensionWithStar) { description = fileExtensionIter->second; break; } } if (!description.empty()) break; } if (description.empty()) { description = std::string("Legacy ") + (*it)->GetNameOfClass() + " Reader"; } - std::cout << "***** CREATING LEGACY WRITER for " << description << std::endl; - mitk::FileWriter::Pointer fileWriter(it->GetPointer()); mitk::LegacyFileWriterService* lfws = new mitk::LegacyFileWriterService(fileWriter, description); m_LegacyWriters.push_back(lfws); } } diff --git a/Core/Code/DataManagement/mitkSurface.cpp b/Core/Code/DataManagement/mitkSurface.cpp index 27a0341c17..843c587744 100644 --- a/Core/Code/DataManagement/mitkSurface.cpp +++ b/Core/Code/DataManagement/mitkSurface.cpp @@ -1,530 +1,529 @@ /*=================================================================== 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 "mitkSurface.h" #include "mitkInteractionConst.h" #include "mitkSurfaceOperation.h" #include #include static vtkPolyData* DeepCopy(vtkPolyData* other) { if (other == NULL) return NULL; vtkPolyData* copy = vtkPolyData::New(); copy->DeepCopy(other); return copy; } static void Delete(vtkPolyData* polyData) { if (polyData != NULL) polyData->Delete(); } static void Update(vtkPolyData* /*polyData*/) { // if (polyData != NULL) // polyData->Update(); //VTK6_TODO vtk pipeline } mitk::Surface::Surface() : m_CalculateBoundingBox(false) { this->InitializeEmpty(); } mitk::Surface::Surface(const mitk::Surface& other) : BaseData(other), m_LargestPossibleRegion(other.m_LargestPossibleRegion), m_RequestedRegion(other.m_RequestedRegion), m_CalculateBoundingBox(other.m_CalculateBoundingBox) { if(!other.m_PolyDatas.empty()) { m_PolyDatas.resize(other.m_PolyDatas.size()); std::transform(other.m_PolyDatas.begin(), other.m_PolyDatas.end(), m_PolyDatas.begin(), DeepCopy); } else { this->InitializeEmpty(); } } void mitk::Surface::Swap(mitk::Surface& other) { std::swap(m_PolyDatas, other.m_PolyDatas); std::swap(m_LargestPossibleRegion, other.m_LargestPossibleRegion); std::swap(m_RequestedRegion, other.m_RequestedRegion); std::swap(m_CalculateBoundingBox, other.m_CalculateBoundingBox); } mitk::Surface& mitk::Surface::operator=(Surface other) { this->Swap(other); return *this; } mitk::Surface::~Surface() { this->ClearData(); } void mitk::Surface::ClearData() { using ::Delete; std::for_each(m_PolyDatas.begin(), m_PolyDatas.end(), Delete); m_PolyDatas.clear(); Superclass::ClearData(); } const mitk::Surface::RegionType& mitk::Surface::GetLargestPossibleRegion() const { m_LargestPossibleRegion.SetIndex(3, 0); m_LargestPossibleRegion.SetSize(3, GetTimeGeometry()->CountTimeSteps()); return m_LargestPossibleRegion; } const mitk::Surface::RegionType& mitk::Surface::GetRequestedRegion() const { return m_RequestedRegion; } void mitk::Surface::InitializeEmpty() { if (!m_PolyDatas.empty()) this->ClearData(); Superclass::InitializeTimeGeometry(); m_PolyDatas.push_back(NULL); m_Initialized = true; } void mitk::Surface::SetVtkPolyData(vtkPolyData* polyData, unsigned int t) { this->Expand(t + 1); if (m_PolyDatas[t] != NULL) { if (m_PolyDatas[t] == polyData) return; m_PolyDatas[t]->Delete(); } m_PolyDatas[t] = polyData; if(polyData != NULL) polyData->Register(NULL); m_CalculateBoundingBox = true; this->Modified(); this->UpdateOutputInformation(); } bool mitk::Surface::IsEmptyTimeStep(unsigned int t) const { if(!IsInitialized()) return false; vtkPolyData* polyData = const_cast(this)->GetVtkPolyData(t); return polyData == NULL || ( polyData->GetNumberOfLines() == 0 && polyData->GetNumberOfPolys() == 0 && polyData->GetNumberOfStrips() == 0 && polyData->GetNumberOfVerts() == 0 ); } -vtkPolyData* mitk::Surface::GetVtkPolyData(unsigned int t) +vtkPolyData* mitk::Surface::GetVtkPolyData(unsigned int t) const { if (t < m_PolyDatas.size()) { if(m_PolyDatas[t] == NULL && this->GetSource().IsNotNull()) { RegionType requestedRegion; requestedRegion.SetIndex(3, t); requestedRegion.SetSize(3, 1); - - this->SetRequestedRegion(&requestedRegion); + this->m_RequestedRegion = requestedRegion; this->GetSource()->Update(); } return m_PolyDatas[t]; } return NULL; } void mitk::Surface::UpdateOutputInformation() { if (this->GetSource().IsNotNull()) this->GetSource()->UpdateOutputInformation(); if (m_CalculateBoundingBox == true && !m_PolyDatas.empty()) this->CalculateBoundingBox(); else this->GetTimeGeometry()->Update(); } void mitk::Surface::CalculateBoundingBox() { TimeGeometry* timeGeometry = this->GetTimeGeometry(); if (timeGeometry->CountTimeSteps() != m_PolyDatas.size()) mitkThrow() << "Number of geometry time steps is inconsistent with number of poly data pointers."; for (unsigned int i = 0; i < m_PolyDatas.size(); ++i) { vtkPolyData* polyData = m_PolyDatas[i]; double bounds[6] = {0}; if (polyData != NULL && polyData->GetNumberOfPoints() > 0) { // polyData->Update(); //VTK6_TODO vtk pipeline polyData->ComputeBounds(); polyData->GetBounds(bounds); } BaseGeometry::Pointer geometry = timeGeometry->GetGeometryForTimeStep(i); if (geometry.IsNull()) mitkThrow() << "Time-sliced geometry is invalid (equals NULL)."; geometry->SetFloatBounds(bounds); } timeGeometry->Update(); m_CalculateBoundingBox = false; } void mitk::Surface::SetRequestedRegionToLargestPossibleRegion() { m_RequestedRegion = GetLargestPossibleRegion(); } bool mitk::Surface::RequestedRegionIsOutsideOfTheBufferedRegion() { RegionType::IndexValueType end = m_RequestedRegion.GetIndex(3) + m_RequestedRegion.GetSize(3); if(static_cast(m_PolyDatas.size()) < end) return true; for(RegionType::IndexValueType t = m_RequestedRegion.GetIndex(3); t < end; ++t) { if(m_PolyDatas[t] == NULL) return true; } return false; } bool mitk::Surface::VerifyRequestedRegion() { if(m_RequestedRegion.GetIndex(3) >= 0 && m_RequestedRegion.GetIndex(3) + m_RequestedRegion.GetSize(3) <= m_PolyDatas.size()) return true; return false; } void mitk::Surface::SetRequestedRegion(const itk::DataObject* data ) { const mitk::Surface *surface = dynamic_cast(data); if (surface != NULL) m_RequestedRegion = surface->GetRequestedRegion(); else mitkThrow() << "Data object used to get requested region is not a mitk::Surface."; } void mitk::Surface::SetRequestedRegion(Surface::RegionType* region) { if (region == NULL) mitkThrow() << "Requested region is invalid (equals NULL)"; m_RequestedRegion = *region; } void mitk::Surface::CopyInformation(const itk::DataObject* data) { Superclass::CopyInformation(data); const mitk::Surface* surface = dynamic_cast(data); if (surface == NULL) mitkThrow() << "Data object used to get largest possible region is not a mitk::Surface."; m_LargestPossibleRegion = surface->GetLargestPossibleRegion(); } void mitk::Surface::Update() { using ::Update; if (this->GetSource().IsNull()) std::for_each(m_PolyDatas.begin(), m_PolyDatas.end(), Update); Superclass::Update(); } void mitk::Surface::Expand(unsigned int timeSteps) { if (timeSteps > m_PolyDatas.size()) { Superclass::Expand(timeSteps); m_PolyDatas.resize(timeSteps); m_CalculateBoundingBox = true; } } void mitk::Surface::ExecuteOperation(Operation* operation) { switch (operation->GetOperationType()) { case OpSURFACECHANGED: { mitk::SurfaceOperation* surfaceOperation = dynamic_cast(operation); if(surfaceOperation == NULL) break; unsigned int timeStep = surfaceOperation->GetTimeStep(); if(m_PolyDatas[timeStep] != NULL) { vtkPolyData* updatedPolyData = surfaceOperation->GetVtkPolyData(); if(updatedPolyData != NULL) { this->SetVtkPolyData(updatedPolyData, timeStep); this->CalculateBoundingBox(); this->Modified(); } } break; } default: return; } } unsigned int mitk::Surface::GetSizeOfPolyDataSeries() const { return m_PolyDatas.size(); } void mitk::Surface::Graft(const DataObject* data) { const Surface* surface = dynamic_cast(data); if(surface == NULL) mitkThrow() << "Data object used to graft surface is not a mitk::Surface."; this->CopyInformation(data); m_PolyDatas.clear(); for (unsigned int i = 0; i < surface->GetSizeOfPolyDataSeries(); ++i) { m_PolyDatas.push_back(vtkPolyData::New()); m_PolyDatas.back()->DeepCopy(const_cast(surface)->GetVtkPolyData(i)); } } void mitk::Surface::PrintSelf(std::ostream& os, itk::Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "\nNumber PolyDatas: " << m_PolyDatas.size() << "\n"; unsigned int count = 0; for (std::vector::const_iterator it = m_PolyDatas.begin(); it != m_PolyDatas.end(); ++it) { os << "\n"; if(*it != NULL) { os << indent << "PolyData at time step " << count << ":\n"; os << indent << "Number of cells: " << (*it)->GetNumberOfCells() << "\n"; os << indent << "Number of points: " << (*it)->GetNumberOfPoints() << "\n\n"; os << indent << "VTKPolyData:\n"; (*it)->Print(os); } else { os << indent << "Empty PolyData at time step " << count << "\n"; } ++count; } } bool mitk::Equal( vtkPolyData* leftHandSide, vtkPolyData* rightHandSide, mitk::ScalarType eps, bool verbose ) { if(( leftHandSide == NULL ) || ( rightHandSide == NULL )) { MITK_ERROR << "mitk::Equal( vtkPolyData* leftHandSide, vtkPolyData* rightHandSide, mitk::ScalarType eps, bool verbose ) does not work for NULL pointer input."; return false; } return Equal( *leftHandSide, *rightHandSide, eps, verbose); } bool mitk::Equal( vtkPolyData& leftHandSide, vtkPolyData& rightHandSide, mitk::ScalarType eps, bool verbose ) { bool noDifferenceFound = true; if( ! mitk::Equal( leftHandSide.GetNumberOfCells(), rightHandSide.GetNumberOfCells(), eps, verbose ) ) { if(verbose) MITK_INFO << "[Equal( vtkPolyData*, vtkPolyData* )] Number of cells not equal"; noDifferenceFound = false; } if( ! mitk::Equal( leftHandSide.GetNumberOfVerts(), rightHandSide.GetNumberOfVerts(), eps, verbose )) { if(verbose) MITK_INFO << "[Equal( vtkPolyData*, vtkPolyData* )] Number of vertices not equal"; noDifferenceFound = false; } if( ! mitk::Equal( leftHandSide.GetNumberOfLines(), rightHandSide.GetNumberOfLines(), eps, verbose ) ) { if(verbose) MITK_INFO << "[Equal( vtkPolyData*, vtkPolyData* )] Number of lines not equal"; noDifferenceFound = false; } if( ! mitk::Equal( leftHandSide.GetNumberOfPolys(), rightHandSide.GetNumberOfPolys(), eps, verbose ) ) { if(verbose) MITK_INFO << "[Equal( vtkPolyData*, vtkPolyData* )] Number of polys not equal"; noDifferenceFound = false; } if( ! mitk::Equal( leftHandSide.GetNumberOfStrips(), rightHandSide.GetNumberOfStrips(), eps, verbose ) ) { if(verbose) MITK_INFO << "[Equal( vtkPolyData*, vtkPolyData* )] Number of strips not equal"; noDifferenceFound = false; } { unsigned int numberOfPointsRight = rightHandSide.GetPoints()->GetNumberOfPoints(); unsigned int numberOfPointsLeft = leftHandSide.GetPoints()->GetNumberOfPoints(); if(! mitk::Equal( numberOfPointsLeft, numberOfPointsRight, eps, verbose )) { if(verbose) MITK_INFO << "[Equal( vtkPolyData*, vtkPolyData* )] Number of points not equal"; noDifferenceFound = false; } else { for( unsigned int i( 0 ); i < numberOfPointsRight; i++ ) { bool pointFound = false; double pointOne[3]; rightHandSide.GetPoints()->GetPoint(i, pointOne); for( unsigned int j( 0 ); j < numberOfPointsLeft; j++ ) { double pointTwo[3]; leftHandSide.GetPoints()->GetPoint(j, pointTwo); double x = pointOne[0] - pointTwo[0]; double y = pointOne[1] - pointTwo[1]; double z = pointOne[2] - pointTwo[2]; double distance = x*x + y*y + z*z; if( distance < eps ) { pointFound = true; break; } } if( !pointFound ) { if(verbose) { MITK_INFO << "[Equal( vtkPolyData*, vtkPolyData* )] Right hand side point with id " << i << " and coordinates ( " << std::setprecision(12) << pointOne[0] << " ; " << pointOne[1] << " ; " << pointOne[2] << " ) could not be found in left hand side with epsilon " << eps << "."; } noDifferenceFound = false; break; } } } } return noDifferenceFound; } bool mitk::Equal( mitk::Surface* leftHandSide, mitk::Surface* rightHandSide, mitk::ScalarType eps, bool verbose ) { if(( leftHandSide == NULL ) || ( rightHandSide == NULL )) { MITK_ERROR << "mitk::Equal( mitk::Surface* leftHandSide, mitk::Surface* rightHandSide, mitk::ScalarType eps, bool verbose ) does not work with NULL pointer input."; return false; } return Equal( *leftHandSide, *rightHandSide, eps, verbose); } bool mitk::Equal( mitk::Surface& leftHandSide, mitk::Surface& rightHandSide, mitk::ScalarType eps, bool verbose ) { bool noDifferenceFound = true; if( ! mitk::Equal( leftHandSide.GetSizeOfPolyDataSeries(), rightHandSide.GetSizeOfPolyDataSeries(), eps, verbose ) ) { if(verbose) MITK_INFO << "[Equal( mitk::surface&, mitk::surface& )] Size of PolyData series not equal."; return false; } // No mitk::Equal for TimeGeometry implemented. //if( ! mitk::Equal( leftHandSide->GetTimeGeometry(), rightHandSide->GetTimeGeometry(), eps, verbose ) ) //{ // if(verbose) // MITK_INFO << "[Equal( mitk::surface&, mitk::surface& )] Time sliced geometries not equal"; // noDifferenceFound = false; //} for( unsigned int i( 0 ); i < rightHandSide.GetSizeOfPolyDataSeries(); i++ ) { if( ! mitk::Equal( *leftHandSide.GetVtkPolyData( i ), *rightHandSide.GetVtkPolyData( i ), eps, verbose ) ) { if(verbose) MITK_INFO << "[Equal( mitk::surface&, mitk::surface& )] Poly datas not equal."; noDifferenceFound = false; } } return noDifferenceFound; } diff --git a/Core/Code/DataManagement/mitkSurface.h b/Core/Code/DataManagement/mitkSurface.h index d88f46f824..83b0244154 100644 --- a/Core/Code/DataManagement/mitkSurface.h +++ b/Core/Code/DataManagement/mitkSurface.h @@ -1,136 +1,136 @@ /*=================================================================== 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 mitkSurface_h #define mitkSurface_h #include "mitkBaseData.h" #include "itkImageRegion.h" class vtkPolyData; namespace mitk { /** * \brief Class for storing surfaces (vtkPolyData). * \ingroup Data */ class MITK_CORE_EXPORT Surface : public BaseData { public: typedef itk::ImageRegion<5> RegionType; mitkClassMacro(Surface, BaseData); itkFactorylessNewMacro(Self) itkCloneMacro(Self) void CalculateBoundingBox(); virtual void CopyInformation(const itk::DataObject *data); virtual void ExecuteOperation(Operation *operation); virtual void Expand( unsigned int timeSteps = 1 ); const RegionType& GetLargestPossibleRegion() const; virtual const RegionType& GetRequestedRegion() const; unsigned int GetSizeOfPolyDataSeries() const; - virtual vtkPolyData* GetVtkPolyData(unsigned int t = 0); + virtual vtkPolyData* GetVtkPolyData(unsigned int t = 0) const; virtual void Graft( const DataObject* data ); virtual bool IsEmptyTimeStep(unsigned int t) const; virtual void PrintSelf( std::ostream& os, itk::Indent indent ) const; virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); virtual void SetRequestedRegion(const itk::DataObject *data); virtual void SetRequestedRegion(Surface::RegionType *region); virtual void SetRequestedRegionToLargestPossibleRegion(); virtual void SetVtkPolyData(vtkPolyData* polydata, unsigned int t = 0); virtual void Swap(Surface& other); virtual void Update(); virtual void UpdateOutputInformation(); virtual bool VerifyRequestedRegion(); protected: mitkCloneMacro(Self); Surface(); virtual ~Surface(); Surface(const Surface& other); Surface& operator=(Surface other); virtual void ClearData(); virtual void InitializeEmpty(); private: std::vector m_PolyDatas; mutable RegionType m_LargestPossibleRegion; - RegionType m_RequestedRegion; + mutable RegionType m_RequestedRegion; bool m_CalculateBoundingBox; }; /** * @brief Equal Compare two surfaces for equality, returns true if found equal. * @warning This method is deprecated and will not be available in the future. Use the \a bool mitk::Equal(const mitk::Surface& s1, const mitk::Surface& s2) instead * @ingroup MITKTestingAPI * @param rightHandSide Surface to compare. * @param leftHandSide Surface to compare. * @param eps Epsilon to use for floating point comparison. Most of the time mitk::eps will be sufficient. * @param verbose Flag indicating if the method should give a detailed console output. * @return True if every comparison is true, false in any other case. */ DEPRECATED( MITK_CORE_EXPORT bool Equal( mitk::Surface* leftHandSide, mitk::Surface* rightHandSide, mitk::ScalarType eps, bool verbose)); /** * @brief Equal Compare two surfaces for equality, returns true if found equal. * @ingroup MITKTestingAPI * @param rightHandSide Surface to compare. * @param leftHandSide Surface to compare. * @param eps Epsilon to use for floating point comparison. Most of the time mitk::eps will be sufficient. * @param verbose Flag indicating if the method should give a detailed console output. * @return True if every comparison is true, false in any other case. */ MITK_CORE_EXPORT bool Equal( mitk::Surface& leftHandSide, mitk::Surface& rightHandSide, mitk::ScalarType eps, bool verbose); /** * @brief Equal Compare two vtk PolyDatas for equality, returns true if found equal. * @warning This method is deprecated and will not be available in the future. Use the \a bool mitk::Equal(const vtkPolyData& p1, const vtkPolyData& p2) instead * @ingroup MITKTestingAPI * @param rightHandSide Surface to compare. * @param leftHandSide Surface to compare. * @param eps Epsilon to use for floating point comparison. Most of the time mitk::eps will be sufficient. * @param verbose Flag indicating if the method should give a detailed console output. * @return True if every comparison is true, false in any other case. * * This will only check if the number of cells, vertices, polygons, stripes and lines is the same and whether * all the two poly datas have the same number of points with the same coordinates. It is not checked whether * all points are correctly connected. */ DEPRECATED( MITK_CORE_EXPORT bool Equal( vtkPolyData* leftHandSide, vtkPolyData* rightHandSide, mitk::ScalarType eps, bool verbose)); /** * @brief Equal Compare two vtk PolyDatas for equality, returns true if found equal. * @ingroup MITKTestingAPI * @param rightHandSide Surface to compare. * @param leftHandSide Surface to compare. * @param eps Epsilon to use for floating point comparison. Most of the time mitk::eps will be sufficient. * @param verbose Flag indicating if the method should give a detailed console output. * @return True if every comparison is true, false in any other case. * * This will only check if the number of cells, vertices, polygons, stripes and lines is the same and whether * all the two poly datas have the same number of points with the same coordinates. It is not checked whether * all points are correctly connected. */ MITK_CORE_EXPORT bool Equal( vtkPolyData& leftHandSide, vtkPolyData& rightHandSide, mitk::ScalarType eps, bool verbose); } #endif diff --git a/Core/Code/IO/mitkAbstractFileIO.cpp b/Core/Code/IO/mitkAbstractFileIO.cpp index 58bf37911a..0789b88c60 100644 --- a/Core/Code/IO/mitkAbstractFileIO.cpp +++ b/Core/Code/IO/mitkAbstractFileIO.cpp @@ -1,164 +1,193 @@ /*=================================================================== 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" #include "mitkCustomMimeType.h" namespace mitk { AbstractFileIO::Options AbstractFileIO::GetReaderOptions() const { return AbstractFileReader::GetOptions(); } us::Any AbstractFileIO::GetReaderOption(const std::string& name) const { return AbstractFileReader::GetOption(name); } void AbstractFileIO::SetReaderOptions(const AbstractFileIO::Options& options) { AbstractFileReader::SetOptions(options); } void AbstractFileIO::SetReaderOption(const std::string& name, const us::Any& value) { AbstractFileReader::SetOption(name, value); } +AbstractFileIO::Options AbstractFileIO::GetWriterOptions() const +{ + return AbstractFileWriter::GetOptions(); +} + +us::Any AbstractFileIO::GetWriterOption(const std::string& name) const +{ + return AbstractFileWriter::GetOption(name); +} + +void AbstractFileIO::SetWriterOptions(const AbstractFileIO::Options& options) +{ + AbstractFileWriter::SetOptions(options); +} + +void AbstractFileIO::SetWriterOption(const std::string& name, const us::Any& value) +{ + AbstractFileWriter::SetOption(name, value); +} + +IFileIO::ConfidenceLevel AbstractFileIO::GetReaderConfidenceLevel() const +{ + return AbstractFileIOReader::GetReaderConfidenceLevel(); +} + +IFileIO::ConfidenceLevel AbstractFileIO::GetWriterConfidenceLevel() const +{ + return AbstractFileIOWriter::GetWriterConfidenceLevel(); +} + std::pair, us::ServiceRegistration > AbstractFileIO::RegisterService(us::ModuleContext* context) { std::pair, us::ServiceRegistration > result; result.first = this->AbstractFileReader::RegisterService(context); + CustomMimeType writerMimeType = this->AbstractFileWriter::GetMimeType(); + if (writerMimeType.GetName().empty() && writerMimeType.GetExtensions().empty()) + { + this->AbstractFileWriter::SetMimeType(CustomMimeType(this->AbstractFileReader::GetRegisteredMimeType().GetName())); + } result.second = this->AbstractFileWriter::RegisterService(context); return result; } AbstractFileIO::AbstractFileIO(const AbstractFileIO& other) : AbstractFileIOReader(other) , AbstractFileIOWriter(other) { } AbstractFileIO::AbstractFileIO(const std::string& baseDataType) : AbstractFileIOReader() , AbstractFileIOWriter(baseDataType) { } AbstractFileIO::AbstractFileIO(const std::string& baseDataType, const CustomMimeType& mimeType, const std::string& description) : AbstractFileIOReader(mimeType, description) - , AbstractFileIOWriter(baseDataType, mimeType, description) -{ -} - -AbstractFileIO::AbstractFileIO(const std::string& baseDataType, const std::string& extension, const std::string& description) - : AbstractFileIOReader(extension, description) - , AbstractFileIOWriter(baseDataType, extension, description) + , AbstractFileIOWriter(baseDataType, CustomMimeType(mimeType.GetName()), description) { } void AbstractFileIO::SetMimeType(const CustomMimeType& mimeType) { this->AbstractFileReader::SetMimeType(mimeType); - this->AbstractFileWriter::SetMimeType(mimeType); + this->AbstractFileWriter::SetMimeType(CustomMimeType(mimeType.GetName())); } CustomMimeType AbstractFileIO::GetMimeType() const { CustomMimeType mimeType = this->AbstractFileReader::GetMimeType(); if (mimeType.GetName() != this->AbstractFileWriter::GetMimeType().GetName()) { MITK_WARN << "Reader and writer mime-tpyes are different, using the mime-type from IFileReader"; } return mimeType; } 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::Options& defaultOptions) { this->AbstractFileReader::SetDefaultOptions(defaultOptions); } AbstractFileIO::Options AbstractFileIO::GetDefaultReaderOptions() const { return this->AbstractFileReader::GetDefaultOptions(); } void AbstractFileIO::SetDefaultWriterOptions(const AbstractFileIO::Options& defaultOptions) { this->AbstractFileWriter::SetDefaultOptions(defaultOptions); } AbstractFileIO::Options 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(); } IFileReader* AbstractFileIO::ReaderClone() const { return this->IOClone(); } IFileWriter* AbstractFileIO::WriterClone() const { return this->IOClone(); } } diff --git a/Core/Code/IO/mitkAbstractFileIO.h b/Core/Code/IO/mitkAbstractFileIO.h index ca85f19099..b66a73dce3 100644 --- a/Core/Code/IO/mitkAbstractFileIO.h +++ b/Core/Code/IO/mitkAbstractFileIO.h @@ -1,181 +1,192 @@ /*=================================================================== 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 { +#ifndef DOXYGEN_SKIP + +// Skip this code during Doxygen processing, because it only +// exists to resolve name clashes when inheriting from both +// AbstractFileReader and AbstractFileWriter. + class AbstractFileIOReader : public AbstractFileReader { public: virtual ConfidenceLevel GetReaderConfidenceLevel() const { return AbstractFileReader::GetConfidenceLevel(); } virtual ConfidenceLevel GetConfidenceLevel() const { return this->GetReaderConfidenceLevel(); } protected: AbstractFileIOReader() {} AbstractFileIOReader(const CustomMimeType& mimeType, const std::string& description) : AbstractFileReader(mimeType, description) {} - AbstractFileIOReader(const std::string& extension, const std::string& description) - : AbstractFileReader(extension, description) {} - private: virtual IFileReader* ReaderClone() const = 0; IFileReader* Clone() const { return ReaderClone(); } }; struct AbstractFileIOWriter : public AbstractFileWriter { virtual ConfidenceLevel GetWriterConfidenceLevel() const { return AbstractFileWriter::GetConfidenceLevel(); } virtual ConfidenceLevel GetConfidenceLevel() const { return this->GetWriterConfidenceLevel(); } protected: AbstractFileIOWriter(const std::string& baseDataType) : AbstractFileWriter(baseDataType) {} AbstractFileIOWriter(const std::string& baseDataType, const CustomMimeType& mimeType, const std::string& description) : AbstractFileWriter(baseDataType, mimeType, description) {} - AbstractFileIOWriter(const std::string& baseDataType, const std::string& extension, - const std::string& description) - : AbstractFileWriter(baseDataType, extension, description) {} - private: virtual IFileWriter* WriterClone() const = 0; IFileWriter* Clone() const { return WriterClone(); } }; +#endif // DOXYGEN_SKIP + class MITK_CORE_EXPORT AbstractFileIO : public AbstractFileIOReader, public AbstractFileIOWriter { public: Options GetReaderOptions() const; us::Any GetReaderOption(const std::string &name) const; void SetReaderOptions(const Options& options); void SetReaderOption(const std::string& name, const us::Any& value); + Options GetWriterOptions() const; + us::Any GetWriterOption(const std::string &name) const; + + void SetWriterOptions(const Options& options); + void SetWriterOption(const std::string& name, const us::Any& value); + + virtual ConfidenceLevel GetReaderConfidenceLevel() const; + + virtual ConfidenceLevel GetWriterConfidenceLevel() const; + std::pair, us::ServiceRegistration > RegisterService(us::ModuleContext* context = us::GetModuleContext()); protected: AbstractFileIO(const AbstractFileIO& other); AbstractFileIO(const std::string& baseDataType); /** * 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 CustomMimeType& 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 on the CustomMimeType object returned by GetMimeType() and * setting the modified object again via SetMimeType(). * * @param extension The file extension (without a leading period) for which a registered * mime-type object is looked up and associated with this 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 CustomMimeType& mimeType); /** * @return The mime-type this reader can handle. */ CustomMimeType GetMimeType() const; void SetReaderDescription(const std::string& description); std::string GetReaderDescription() const; void SetWriterDescription(const std::string& description); std::string GetWriterDescription() const; void SetDefaultReaderOptions(const Options& defaultOptions); Options GetDefaultReaderOptions() const; void SetDefaultWriterOptions(const Options& defaultOptions); Options 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* IOClone() const = 0; virtual IFileReader* ReaderClone() const; virtual IFileWriter* WriterClone() const; }; } #endif // MITKABSTRACTFILEIO_H diff --git a/Core/Code/IO/mitkAbstractFileReader.cpp b/Core/Code/IO/mitkAbstractFileReader.cpp index 3af2e1d946..c03e03d3fd 100644 --- a/Core/Code/IO/mitkAbstractFileReader.cpp +++ b/Core/Code/IO/mitkAbstractFileReader.cpp @@ -1,403 +1,399 @@ /*=================================================================== 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 { AbstractFileReader::InputStream::InputStream(IFileReader* reader, std::ios_base::openmode mode) : std::istream(NULL) , m_Stream(NULL) { std::istream* stream = reader->GetInputStream(); if (stream) { this->init(stream->rdbuf()); } else { m_Stream = new std::ifstream(reader->GetInputLocation().c_str(), mode); this->init(m_Stream->rdbuf()); } } AbstractFileReader::InputStream::~InputStream() { delete m_Stream; } class AbstractFileReader::Impl : public FileReaderWriterBase { public: Impl() : FileReaderWriterBase() , m_Stream(NULL) , m_PrototypeFactory(NULL) {} Impl(const Impl& other) : FileReaderWriterBase(other) , m_Stream(NULL) , m_PrototypeFactory(NULL) {} std::string m_Location; std::string m_TmpFile; std::istream* m_Stream; us::PrototypeServiceFactory* m_PrototypeFactory; us::ServiceRegistration m_Reg; }; AbstractFileReader::AbstractFileReader() : d(new Impl) { } AbstractFileReader::~AbstractFileReader() { UnregisterService(); delete d->m_PrototypeFactory; if (!d->m_TmpFile.empty()) { std::remove(d->m_TmpFile.c_str()); } } AbstractFileReader::AbstractFileReader(const AbstractFileReader& other) : IFileReader(), d(new Impl(*other.d.get())) { } AbstractFileReader::AbstractFileReader(const CustomMimeType& 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) -{ - CustomMimeType customMimeType; - customMimeType.AddExtension(extension); - d->SetMimeType(customMimeType); - d->SetDescription(description); -} - ////////////////////// Reading ///////////////////////// DataStorage::SetOfObjects::Pointer AbstractFileReader::Read(DataStorage& ds) { DataStorage::SetOfObjects::Pointer result = DataStorage::SetOfObjects::New(); std::vector data = this->Read(); for (std::vector::iterator iter = data.begin(); iter != data.end(); ++iter) { mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(*iter); this->SetDefaultDataNodeProperties(node, this->GetInputLocation()); ds.Add(node); result->InsertElement(result->Size(), node); } return result; } IFileReader::ConfidenceLevel AbstractFileReader::GetConfidenceLevel() const { if (d->m_Stream) { if (*d->m_Stream) return Supported; } else { if (itksys::SystemTools::FileExists(this->GetInputLocation().c_str(), true)) { return Supported; } } return Unsupported; } //////////// µ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().GetName().empty()) { 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(); 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().GetName(); result[us::ServiceConstants::SERVICE_RANKING()] = this->GetRanking(); return result; } us::ServiceRegistration AbstractFileReader::RegisterMimeType(us::ModuleContext* context) { return d->RegisterMimeType(context); } void AbstractFileReader::SetMimeType(const CustomMimeType& mimeType) { d->SetMimeType(mimeType); } 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(); } std::string AbstractFileReader::GetLocalFileName() const { std::string localFileName; if (d->m_Stream) { if (d->m_TmpFile.empty()) { // write the stream contents to temporary file std::string ext = itksys::SystemTools::GetFilenameExtension(this->GetInputLocation()); std::ofstream tmpStream; localFileName = mitk::IOUtil::CreateTemporaryFile(tmpStream, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary, "XXXXXX" + ext); tmpStream << d->m_Stream->rdbuf(); d->m_TmpFile = localFileName; } else { localFileName = d->m_TmpFile; } } else { localFileName = d->m_Location; } return localFileName; } //////////////////////// Options /////////////////////// void AbstractFileReader::SetDefaultOptions(const IFileReader::Options& defaultOptions) { d->SetDefaultOptions(defaultOptions); } IFileReader::Options AbstractFileReader::GetDefaultOptions() const { return d->GetDefaultOptions(); } void AbstractFileReader::SetInput(const std::string& location) { d->m_Location = location; d->m_Stream = NULL; } void AbstractFileReader::SetInput(const std::string& location, std::istream* is) { if (d->m_Stream != is && !d->m_TmpFile.empty()) { std::remove(d->m_TmpFile.c_str()); d->m_TmpFile.clear(); } d->m_Location = location; d->m_Stream = is; } std::string AbstractFileReader::GetInputLocation() const { return d->m_Location; } std::istream*AbstractFileReader::GetInputStream() const { return d->m_Stream; } +MimeType AbstractFileReader::GetRegisteredMimeType() const +{ + return d->GetRegisteredMimeType(); +} + 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 ////////////////// void AbstractFileReader::AddProgressCallback(const ProgressCallback& callback) { d->AddProgressCallback(callback); } void AbstractFileReader::RemoveProgressCallback(const ProgressCallback& callback) { d->RemoveProgressCallback(callback); } ////////////////// µS related Getters ////////////////// CustomMimeType AbstractFileReader::GetMimeType() const { return d->GetMimeType(); } void AbstractFileReader::SetMimeTypePrefix(const std::string& prefix) { d->SetMimeTypePrefix(prefix); } std::string AbstractFileReader::GetMimeTypePrefix() const { return d->GetMimeTypePrefix(); } std::string AbstractFileReader::GetDescription() const { return d->GetDescription(); } 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 5e01a2000f..de905aa836 100644 --- a/Core/Code/IO/mitkAbstractFileReader.h +++ b/Core/Code/IO/mitkAbstractFileReader.h @@ -1,236 +1,231 @@ /*=================================================================== 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 { class CustomMimeType; /** * @brief Base class for creating mitk::BaseData objects from files or streams. * @ingroup IO */ class MITK_CORE_EXPORT AbstractFileReader : public mitk::IFileReader { public: virtual void SetInput(const std::string& location); virtual void SetInput(const std::string &location, std::istream* is); virtual std::string GetInputLocation() const; virtual std::istream* GetInputStream() const; + MimeType GetRegisteredMimeType() const; + /** * @brief Reads a path or stream and creates a list of BaseData objects. * * This method must be implemented for each specific reader. Call * GetInputStream() first and check for a non-null stream to read from. * If the input stream is \c NULL, use GetInputLocation() to read from a local * file-system path. * * If the reader cannot use streams directly, use GetLocalFileName() instead. * * @return The created BaseData objects. * @throws mitk::Exception * * @see GetLocalFileName() * @see IFileReader::Read() */ virtual std::vector > Read() = 0; virtual DataStorage::SetOfObjects::Pointer Read(mitk::DataStorage& ds); virtual ConfidenceLevel GetConfidenceLevel() const; 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); /** * 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 * mime-type 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: /** * @brief An input stream wrapper. * * If a reader can only work with input streams, use an instance * of this class to either wrap the specified input stream or * create a new input stream based on the input location in the * file system. */ class InputStream : public std::istream { public: InputStream(IFileReader* writer, std::ios_base::openmode mode = std::ios_base::in); ~InputStream(); private: std::istream* m_Stream; }; AbstractFileReader(); ~AbstractFileReader(); AbstractFileReader(const AbstractFileReader& other); /** * Associate this reader instance with the given MIME type. * + * If \c mimeType does not provide an extension list, an already + * registered mime-type object is used. Otherwise, the first entry in + * the extensions list is used to construct a mime-type name and + * register it as a new CustomMimeType service object in the default + * implementation of RegisterMimeType(). + * * @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 CustomMimeType& 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 - * mime-type 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 CustomMimeType service object. * * This method is called from RegisterService and the default implementation * registers a new mime-type service object if all of the following conditions * are true: * * - TODO * * @param context * @return * @throws std::invalid_argument if \c context is NULL. */ virtual us::ServiceRegistration RegisterMimeType(us::ModuleContext* context); void SetMimeType(const CustomMimeType& mimeType); /** * @return The mime-type this reader can handle. */ CustomMimeType GetMimeType() const; void SetMimeTypePrefix(const std::string& prefix); std::string GetMimeTypePrefix() const; 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; /** * @brief Get a local file name for reading. * * This is a convenience method for readers which cannot work natively * with input streams. If no input stream has been been set, * this method just returns the result of GetLocation(). However, if * SetLocation(std::string, std::istream*) has been called with a non-null * input stream, this method writes the contents of the stream to a temporary * file and returns the name of the temporary file. * * The temporary file is deleted when either SetLocation(std::string, std::istream*) * is called again with a different input stream or the destructor of this * class is called. * * This method does not validate file names set via SetInput(std::string). * * @return A file path in the local file-system for reading. */ std::string GetLocalFileName() 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 149d6dee47..0fa5c0a066 100644 --- a/Core/Code/IO/mitkAbstractFileWriter.cpp +++ b/Core/Code/IO/mitkAbstractFileWriter.cpp @@ -1,387 +1,395 @@ /*=================================================================== 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 #include #include namespace mitk { struct AbstractFileWriter::LocalFile::Impl { Impl(const std::string& location, std::ostream* os) : m_Location(location) , m_Stream(os) {} std::string m_Location; std::string m_TmpFileName; std::ostream* m_Stream; }; AbstractFileWriter::LocalFile::LocalFile(IFileWriter *writer) : d(new Impl(writer->GetOutputLocation(), writer->GetOutputStream())) { } AbstractFileWriter::LocalFile::~LocalFile() { if (d->m_Stream && !d->m_TmpFileName.empty()) { std::ifstream ifs(d->m_TmpFileName.c_str(), std::ios_base::binary); *d->m_Stream << ifs.rdbuf(); d->m_Stream->flush(); ifs.close(); std::remove(d->m_TmpFileName.c_str()); } } std::string AbstractFileWriter::LocalFile::GetFileName() { if (d->m_Stream == NULL) { return d->m_Location; } else if (d->m_TmpFileName.empty()) { std::string ext = itksys::SystemTools::GetFilenameExtension(d->m_Location); d->m_TmpFileName = IOUtil::CreateTemporaryFile("XXXXXX" + ext); } return d->m_TmpFileName; } AbstractFileWriter::OutputStream::OutputStream(IFileWriter* writer, std::ios_base::openmode mode) : std::ostream(NULL) , m_Stream(NULL) { std::ostream* stream = writer->GetOutputStream(); if (stream) { this->init(stream->rdbuf()); } else { m_Stream = new std::ofstream(writer->GetOutputLocation().c_str(), mode); this->init(m_Stream->rdbuf()); } } AbstractFileWriter::OutputStream::~OutputStream() { delete m_Stream; } class AbstractFileWriter::Impl : public FileReaderWriterBase { public: Impl() : FileReaderWriterBase() , m_BaseData(NULL) , m_Stream(NULL) , m_PrototypeFactory(NULL) {} Impl(const Impl& other) : FileReaderWriterBase(other) , m_BaseDataType(other.m_BaseDataType) , m_BaseData(NULL) , m_Stream(NULL) , m_PrototypeFactory(NULL) {} std::string m_BaseDataType; const BaseData* m_BaseData; std::string m_Location; std::ostream* m_Stream; us::PrototypeServiceFactory* m_PrototypeFactory; us::ServiceRegistration m_Reg; }; void AbstractFileWriter::SetInput(const BaseData* data) { d->m_BaseData = data; } const BaseData* AbstractFileWriter::GetInput() const { return d->m_BaseData; } void AbstractFileWriter::SetOutputLocation(const std::string& location) { d->m_Location = location; d->m_Stream = NULL; } std::string AbstractFileWriter::GetOutputLocation() const { return d->m_Location; } void AbstractFileWriter::SetOutputStream(const std::string& location, std::ostream* os) { d->m_Location = location; d->m_Stream = os; } std::ostream* AbstractFileWriter::GetOutputStream() const { return d->m_Stream; } AbstractFileWriter::~AbstractFileWriter() { UnregisterService(); delete d->m_PrototypeFactory; } AbstractFileWriter::AbstractFileWriter(const AbstractFileWriter& other) : IFileWriter(), d(new Impl(*other.d.get())) { } AbstractFileWriter::AbstractFileWriter(const std::string& baseDataType) : d(new Impl) { d->m_BaseDataType = baseDataType; } AbstractFileWriter::AbstractFileWriter(const std::string& baseDataType, const CustomMimeType& 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); - CustomMimeType customMimeType; - customMimeType.AddExtension(extension); - d->SetMimeType(customMimeType); -} - ////////////////////// Writing ///////////////////////// IFileWriter::ConfidenceLevel AbstractFileWriter::GetConfidenceLevel() const { if (d->m_BaseData == NULL) return Unsupported; std::vector classHierarchy = d->m_BaseData->GetClassHierarchy(); if (std::find(classHierarchy.begin(), classHierarchy.end(), d->m_BaseDataType) == classHierarchy.end()) { return Unsupported; } return Supported; } +MimeType AbstractFileWriter::GetRegisteredMimeType() const +{ + return d->GetRegisteredMimeType(); +} + //////////// µ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().GetName().empty()) { 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(); 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().GetName(); 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; } CustomMimeType AbstractFileWriter::GetMimeType() const { return d->GetMimeType(); } void AbstractFileWriter::SetMimeTypePrefix(const std::string& prefix) { d->SetMimeTypePrefix(prefix); } std::string AbstractFileWriter::GetMimeTypePrefix() const { return d->GetMimeTypePrefix(); } us::ServiceRegistration AbstractFileWriter::RegisterMimeType(us::ModuleContext* context) { return d->RegisterMimeType(context); } void AbstractFileWriter::SetMimeType(const CustomMimeType& 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(); } 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::ValidateOutputLocation() const +{ + if (this->GetOutputStream() == NULL) + { + // check if a file name is set and if we can write to it + const std::string fileName = this->GetOutputLocation(); + if (fileName.empty()) + { + mitkThrow() << "No output location or stream specified"; + } + } +} + void AbstractFileWriter::SetDescription(const std::string& description) { d->SetDescription(description); } } diff --git a/Core/Code/IO/mitkAbstractFileWriter.h b/Core/Code/IO/mitkAbstractFileWriter.h index 77b5f2a919..a9620eff97 100644 --- a/Core/Code/IO/mitkAbstractFileWriter.h +++ b/Core/Code/IO/mitkAbstractFileWriter.h @@ -1,229 +1,232 @@ /*=================================================================== 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 { class CustomMimeType; /** * @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 IO */ class MITK_CORE_EXPORT AbstractFileWriter : public mitk::IFileWriter { public: virtual void SetInput(const BaseData* data); virtual const BaseData* GetInput() const; virtual void SetOutputLocation(const std::string& location); virtual std::string GetOutputLocation() const; virtual void SetOutputStream(const std::string& location, std::ostream* os); virtual std::ostream* GetOutputStream() const; /** * \brief Write the base data to the specified location or output stream. * * This method must be implemented for each specific writer. Call * GetOutputStream() first and check for a non-null stream to write to. * If the output stream is \c NULL, use GetOutputLocation() to write * to a local file-system path. * * If the reader cannot use streams directly, use GetLocalFile() to retrieve * a temporary local file name instead. * * \throws mitk::Exception * * \see GetLocalFile() * \see IFileWriter::Write() */ virtual void Write() = 0; virtual ConfidenceLevel GetConfidenceLevel() const; + MimeType GetRegisteredMimeType() const; + 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: /** * @brief A local file representation for streams. * * If a writer can only work with local files, use an instance * of this class to get either a temporary file name for writing * to the specified output stream or the original output location * if no output stream was set. */ class LocalFile { public: LocalFile(IFileWriter* writer); // Writes to the ostream and removes the temporary file ~LocalFile(); // Creates a temporary file for output operations. std::string GetFileName(); private: // disabled LocalFile(); LocalFile(const LocalFile&); LocalFile& operator=(const LocalFile& other); struct Impl; std::auto_ptr d; }; /** * @brief An output stream wrapper. * * If a writer can only work with output streams, use an instance * of this class to either wrap the specified output stream or * create a new output stream based on the output location in the * file system. */ class OutputStream : public std::ostream { public: OutputStream(IFileWriter* writer, std::ios_base::openmode mode = std::ios_base::trunc | std::ios_base::out); ~OutputStream(); private: std::ostream* m_Stream; }; ~AbstractFileWriter(); AbstractFileWriter(const AbstractFileWriter& other); AbstractFileWriter(const std::string& baseDataType); AbstractFileWriter(const std::string& baseDataType, const CustomMimeType& 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 CustomMimeType service object. * * This method is called from RegisterService and the default implementation * registers a new mime-type service object if all of the following conditions * are true: * * - TODO * * @param context * @return * @throws std::invalid_argument if \c context is NULL. */ virtual us::ServiceRegistration RegisterMimeType(us::ModuleContext* context); void SetMimeType(const CustomMimeType& mimeType); /** * @return Get the mime-type this writer can handle. */ CustomMimeType GetMimeType() const; void SetMimeTypePrefix(const std::string& prefix); std::string GetMimeTypePrefix() const; /** * \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; + void ValidateOutputLocation() 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/IO/mitkFileWriterSelector.cpp b/Core/Code/IO/mitkFileWriterSelector.cpp index 62efdc562d..09bbaed9fa 100644 --- a/Core/Code/IO/mitkFileWriterSelector.cpp +++ b/Core/Code/IO/mitkFileWriterSelector.cpp @@ -1,359 +1,361 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkFileWriterSelector.h" #include #include #include #include #include #include #include #include #include #include #include namespace mitk { struct FileWriterSelector::Item::Impl : us::SharedData { Impl() : m_FileWriter(NULL) , m_ConfidenceLevel(IFileWriter::Unsupported) , m_BaseDataIndex(0) , m_Id(-1) {} us::ServiceReference m_FileWriterRef; IFileWriter* m_FileWriter; IFileWriter::ConfidenceLevel m_ConfidenceLevel; std::size_t m_BaseDataIndex; MimeType m_MimeType; long m_Id; }; struct FileWriterSelector::Impl : us::SharedData { Impl() : m_BestId(-1) , m_SelectedId(m_BestId) {} Impl(const Impl& other) : us::SharedData(other) , m_BestId(-1) , m_SelectedId(m_BestId) {} FileWriterRegistry m_WriterRegistry; std::map m_Items; std::set m_MimeTypes; long m_BestId; long m_SelectedId; }; FileWriterSelector::FileWriterSelector(const FileWriterSelector& other) : m_Data(other.m_Data) { } FileWriterSelector::FileWriterSelector(const BaseData* baseData, const std::string& mimeType, const std::string& path) : m_Data(new Impl) { mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); std::string destMimeType = mimeType; if (destMimeType.empty() && !path.empty()) { // try to derive a mime-type from the extension std::string ext = itksys::SystemTools::GetFilenameExtension(path); if (ext.size() > 1) { std::vector mimeTypes = mimeTypeProvider->GetMimeTypesForExtension(ext.substr(1)); if (!mimeTypes.empty()) { destMimeType = mimeTypes.front().GetName(); } + else + { + // if both mimeType is empty and path does not contain a known + // extension, we stop here + return; + } } } std::vector classHierarchy = baseData->GetClassHierarchy(); // Get all writers and their mime types for the given base data type std::vector refs = m_Data->m_WriterRegistry.GetReferences(baseData, destMimeType); - us::ServiceReference bestRef; + Item bestItem; for (std::vector::const_iterator iter = refs.begin(), iterEnd = refs.end(); iter != iterEnd; ++iter) { std::string mimeTypeName = iter->GetProperty(IFileWriter::PROP_MIMETYPE()).ToString(); if (!mimeTypeName.empty()) { MimeType mimeType = mimeTypeProvider->GetMimeTypeForName(mimeTypeName); if (mimeType.IsValid()) { // There is a registered mime-type for this writer. Now get the confidence level // of this writer for writing the given base data object. IFileWriter* writer = m_Data->m_WriterRegistry.GetWriter(*iter); if (writer == NULL) continue; try { writer->SetInput(baseData); IFileWriter::ConfidenceLevel confidenceLevel = writer->GetConfidenceLevel(); - std::cout << confidenceLevel << std::endl; if (confidenceLevel == IFileWriter::Unsupported) { continue; } std::string baseDataType = iter->GetProperty(IFileWriter::PROP_BASEDATA_TYPE()).ToString(); std::vector::iterator idxIter = std::find(classHierarchy.begin(), classHierarchy.end(), baseDataType); std::size_t baseDataIndex = std::numeric_limits::max(); if (idxIter != classHierarchy.end()) { baseDataIndex = std::distance(classHierarchy.begin(), idxIter); } Item item; item.d->m_FileWriterRef = *iter; item.d->m_FileWriter = writer; item.d->m_ConfidenceLevel = confidenceLevel; item.d->m_BaseDataIndex = baseDataIndex; item.d->m_MimeType = mimeType; item.d->m_Id = us::any_cast(iter->GetProperty(us::ServiceConstants::SERVICE_ID())); m_Data->m_Items.insert(std::make_pair(item.d->m_Id, item)); m_Data->m_MimeTypes.insert(mimeType); - if (!bestRef || bestRef < *iter) + if (!bestItem.GetReference() || bestItem < item) { - bestRef = *iter; + bestItem = item; } } catch (const us::BadAnyCastException& e) { MITK_WARN << "Unexpected: " << e.what(); } catch (const std::exception& e) { // Log the error but continue MITK_WARN << "IFileWriter::GetConfidenceLevel exception: " << e.what(); } } } } - if (bestRef) + if (bestItem.GetReference()) { - try - { - m_Data->m_BestId = us::any_cast(bestRef.GetProperty(us::ServiceConstants::SERVICE_ID())); - m_Data->m_SelectedId = m_Data->m_BestId; - } catch (const us::BadAnyCastException&) {} + m_Data->m_BestId = bestItem.GetServiceId(); + m_Data->m_SelectedId = m_Data->m_BestId; } } FileWriterSelector::~FileWriterSelector() { } FileWriterSelector& FileWriterSelector::operator=(const FileWriterSelector& other) { m_Data = other.m_Data; return *this; } bool FileWriterSelector::IsEmpty() const { return m_Data->m_Items.empty(); } std::vector FileWriterSelector::Get(const std::string& mimeType) const { std::vector result; for (std::map::const_iterator iter = m_Data->m_Items.begin(), iterEnd = m_Data->m_Items.end(); iter != iterEnd; ++iter) { if (mimeType.empty() || iter->second.GetMimeType().GetName() == mimeType) { result.push_back(iter->second); } } std::sort(result.begin(), result.end()); return result; } std::vector FileWriterSelector::Get() const { return Get(this->GetSelected().d->m_MimeType.GetName()); } FileWriterSelector::Item FileWriterSelector::Get(long id) const { std::map::const_iterator iter = m_Data->m_Items.find(id); if (iter != m_Data->m_Items.end()) { return iter->second; } return Item(); } FileWriterSelector::Item FileWriterSelector::GetDefault() const { return Get(m_Data->m_BestId); } long FileWriterSelector::GetDefaultId() const { return m_Data->m_BestId; } FileWriterSelector::Item FileWriterSelector::GetSelected() const { return Get(m_Data->m_SelectedId); } long FileWriterSelector::GetSelectedId() const { return m_Data->m_SelectedId; } bool FileWriterSelector::Select(const std::string& mimeType) { std::vector items = Get(mimeType); if (items.empty()) return false; return Select(items.back()); } bool FileWriterSelector::Select(const FileWriterSelector::Item& item) { return Select(item.d->m_Id); } bool FileWriterSelector::Select(long id) { if (id > -1) { if (m_Data->m_Items.find(id) == m_Data->m_Items.end()) { return false; } m_Data->m_SelectedId = id; return true; } return false; } std::vector FileWriterSelector::GetMimeTypes() const { std::vector result; result.reserve(m_Data->m_MimeTypes.size()); result.assign(m_Data->m_MimeTypes.begin(), m_Data->m_MimeTypes.end()); return result; } void FileWriterSelector::Swap(FileWriterSelector& fws) { m_Data.Swap(fws.m_Data); } FileWriterSelector::Item::Item(const FileWriterSelector::Item& other) : d(other.d) { } FileWriterSelector::Item::~Item() { } FileWriterSelector::Item& FileWriterSelector::Item::operator=(const FileWriterSelector::Item& other) { d = other.d; return *this; } IFileWriter* FileWriterSelector::Item::GetWriter() const { return d->m_FileWriter; } std::string FileWriterSelector::Item::GetDescription() const { us::Any descr = d->m_FileWriterRef.GetProperty(IFileWriter::PROP_DESCRIPTION()); if (descr.Empty()) return std::string(); return descr.ToString(); } IFileWriter::ConfidenceLevel FileWriterSelector::Item::GetConfidenceLevel() const { return d->m_ConfidenceLevel; } MimeType FileWriterSelector::Item::GetMimeType() const { return d->m_MimeType; } std::string FileWriterSelector::Item::GetBaseDataType() const { us::Any any = d->m_FileWriterRef.GetProperty(IFileWriter::PROP_BASEDATA_TYPE()); if (any.Empty()) return std::string(); return any.ToString(); } us::ServiceReference FileWriterSelector::Item::GetReference() const { return d->m_FileWriterRef; } long FileWriterSelector::Item::GetServiceId() const { return d->m_Id; } bool FileWriterSelector::Item::operator<(const FileWriterSelector::Item& other) const { // sort by confidence level first (ascending) if (d->m_ConfidenceLevel == other.d->m_ConfidenceLevel) { // sort by class hierarchy index (writers for more derived // based data types are considered a better match) if (d->m_BaseDataIndex == other.d->m_BaseDataIndex) { // sort by file writer service ranking return d->m_FileWriterRef < other.d->m_FileWriterRef; } return other.d->m_BaseDataIndex < d->m_BaseDataIndex; } return d->m_ConfidenceLevel < other.d->m_ConfidenceLevel; } FileWriterSelector::Item::Item() : d(new Impl()) {} void swap(FileWriterSelector& fws1, FileWriterSelector& fws2) { fws1.Swap(fws2); } } diff --git a/Core/Code/IO/mitkIOMimeTypes.cpp b/Core/Code/IO/mitkIOMimeTypes.cpp new file mode 100644 index 0000000000..cd2e7c6023 --- /dev/null +++ b/Core/Code/IO/mitkIOMimeTypes.cpp @@ -0,0 +1,225 @@ +/*=================================================================== + +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 "mitkIOMimeTypes.h" + +#include "mitkCustomMimeType.h" + +namespace mitk { + +std::vector IOMimeTypes::Get() +{ + std::vector mimeTypes; + + // order matters here (descending rank for mime types) + + mimeTypes.push_back(NRRD_MIMETYPE()); + mimeTypes.push_back(NIFTI_MIMETYPE()); + + mimeTypes.push_back(VTK_IMAGE_MIMETYPE()); + mimeTypes.push_back(VTK_PARALLEL_IMAGE_MIMETYPE()); + mimeTypes.push_back(VTK_IMAGE_LEGACY_MIMETYPE()); + + mimeTypes.push_back(VTK_POLYDATA_MIMETYPE()); + mimeTypes.push_back(VTK_PARALLEL_POLYDATA_MIMETYPE()); + mimeTypes.push_back(VTK_POLYDATA_LEGACY_MIMETYPE()); + + mimeTypes.push_back(STEREOLITHOGRAPHY_MIMETYPE()); + + mimeTypes.push_back(RAW_MIMETYPE()); + mimeTypes.push_back(POINTSET_MIMETYPE()); + return mimeTypes; +} + +CustomMimeType IOMimeTypes::VTK_IMAGE_MIMETYPE() +{ + CustomMimeType mimeType(VTK_IMAGE_NAME()); + mimeType.AddExtension("vti"); + mimeType.SetCategory("Images"); + mimeType.SetComment("VTK Image"); + return mimeType; +} + +CustomMimeType IOMimeTypes::VTK_IMAGE_LEGACY_MIMETYPE() +{ + CustomMimeType mimeType(VTK_IMAGE_LEGACY_NAME()); + mimeType.AddExtension("vtk"); + mimeType.SetCategory("Images"); + mimeType.SetComment("VTK Legacy Image"); + return mimeType; +} + +CustomMimeType IOMimeTypes::VTK_PARALLEL_IMAGE_MIMETYPE() +{ + CustomMimeType mimeType(VTK_PARALLEL_IMAGE_NAME()); + mimeType.AddExtension("pvti"); + mimeType.SetCategory("Images"); + mimeType.SetComment("VTK Parallel Image"); + return mimeType; +} + +CustomMimeType IOMimeTypes::VTK_POLYDATA_MIMETYPE() +{ + CustomMimeType mimeType(VTK_POLYDATA_NAME()); + mimeType.AddExtension("vtp"); + mimeType.SetCategory("Surfaces"); + mimeType.SetComment("VTK PolyData"); + return mimeType; +} + +CustomMimeType IOMimeTypes::VTK_POLYDATA_LEGACY_MIMETYPE() +{ + CustomMimeType mimeType(VTK_POLYDATA_LEGACY_NAME()); + mimeType.AddExtension("vtk"); + mimeType.SetCategory("Surfaces"); + mimeType.SetComment("VTK Legacy PolyData"); + return mimeType; +} + +CustomMimeType IOMimeTypes::VTK_PARALLEL_POLYDATA_MIMETYPE() +{ + CustomMimeType mimeType(VTK_PARALLEL_POLYDATA_NAME()); + mimeType.AddExtension("pvtp"); + mimeType.SetCategory("Surfaces"); + mimeType.SetComment("VTK Parallel PolyData"); + return mimeType; +} + +CustomMimeType IOMimeTypes::STEREOLITHOGRAPHY_MIMETYPE() +{ + CustomMimeType mimeType(STEREOLITHOGRAPHY_NAME()); + mimeType.AddExtension("stl"); + mimeType.SetCategory("Surfaces"); + mimeType.SetComment("Stereolithography"); + return mimeType; +} + +std::string IOMimeTypes::STEREOLITHOGRAPHY_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".stl"; + return name; +} + +std::string IOMimeTypes::DEFAULT_BASE_NAME() +{ + static std::string name = "application/vnd.mitk"; + return name; +} + +std::string IOMimeTypes::VTK_IMAGE_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".vtk.image"; + return name; +} + +std::string IOMimeTypes::VTK_IMAGE_LEGACY_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".vtk.image.legacy"; + return name; +} + +std::string IOMimeTypes::VTK_PARALLEL_IMAGE_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".vtk.parallel.image"; + return name; +} + +std::string IOMimeTypes::VTK_POLYDATA_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".vtk.polydata"; + return name; +} + +std::string IOMimeTypes::VTK_POLYDATA_LEGACY_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".vtk.polydata.legacy"; + return name; +} + +std::string IOMimeTypes::VTK_PARALLEL_POLYDATA_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".vtk.parallel.polydata"; + return name; +} + +CustomMimeType IOMimeTypes::NRRD_MIMETYPE() +{ + CustomMimeType mimeType(NRRD_MIMETYPE_NAME()); + mimeType.AddExtension("nrrd"); + mimeType.AddExtension("nhdr"); + mimeType.SetCategory("Images"); + mimeType.SetComment("NRRD"); + return mimeType; +} + +CustomMimeType IOMimeTypes::NIFTI_MIMETYPE() +{ + CustomMimeType mimeType(NIFTI_MIMETYPE_NAME()); + mimeType.AddExtension("nii"); + mimeType.AddExtension("nii.gz"); + mimeType.AddExtension("hdr"); + mimeType.AddExtension("img"); + mimeType.AddExtension("img.gz"); + mimeType.AddExtension("img.gz"); + mimeType.AddExtension("nia"); + mimeType.SetCategory("Images"); + mimeType.SetComment("Nifti"); + return mimeType; +} + +CustomMimeType IOMimeTypes::RAW_MIMETYPE() +{ + CustomMimeType mimeType(RAW_MIMETYPE_NAME()); + mimeType.AddExtension("raw"); + mimeType.SetCategory("Images"); + mimeType.SetComment("Raw data"); + return mimeType; +} + +std::string IOMimeTypes::NRRD_MIMETYPE_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".image.nrrd"; + return name; +} + +std::string IOMimeTypes::NIFTI_MIMETYPE_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".image.nifti"; + return name; +} + +std::string IOMimeTypes::RAW_MIMETYPE_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".image.raw"; + return name; +} + +CustomMimeType IOMimeTypes::POINTSET_MIMETYPE() +{ + CustomMimeType mimeType(POINTSET_MIMETYPE_NAME()); + mimeType.AddExtension("mps"); + mimeType.SetCategory("Point Sets"); + mimeType.SetComment("MITK Point Set"); + return mimeType; +} + +std::string IOMimeTypes::POINTSET_MIMETYPE_NAME() +{ + static std::string name = DEFAULT_BASE_NAME() + ".pointset"; + return name; +} + +} diff --git a/Core/Code/IO/mitkIOMimeTypes.h b/Core/Code/IO/mitkIOMimeTypes.h new file mode 100644 index 0000000000..7645aadeab --- /dev/null +++ b/Core/Code/IO/mitkIOMimeTypes.h @@ -0,0 +1,77 @@ +/*=================================================================== + +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 MITKIOMIMETYPES_H +#define MITKIOMIMETYPES_H + +#include "mitkCustomMimeType.h" + +#include + +namespace mitk { + +class IOMimeTypes +{ +public: + + static std::vector Get(); + + static std::string DEFAULT_BASE_NAME(); // application/vnd.mitk + + // ------------------------------ VTK formats ---------------------------------- + + static CustomMimeType VTK_IMAGE_MIMETYPE(); // (mitk::Image) vti + static CustomMimeType VTK_IMAGE_LEGACY_MIMETYPE(); // (mitk::Image) vtk + static CustomMimeType VTK_PARALLEL_IMAGE_MIMETYPE(); // (mitk::Image) pvti + static CustomMimeType VTK_POLYDATA_MIMETYPE(); // (mitk::Surface) vtp, vtk + static CustomMimeType VTK_POLYDATA_LEGACY_MIMETYPE(); // (mitk::Surface) vtk + static CustomMimeType VTK_PARALLEL_POLYDATA_MIMETYPE(); // (mitk::Surface) pvtp + static CustomMimeType STEREOLITHOGRAPHY_MIMETYPE(); // (mitk::Surface) stl + + static std::string STEREOLITHOGRAPHY_NAME(); // DEFAULT_BASE_NAME.stl + static std::string VTK_IMAGE_NAME(); // DEFAULT_BASE_NAME.vtk.image + static std::string VTK_IMAGE_LEGACY_NAME(); // DEFAULT_BASE_NAME.vtk.image.legacy + static std::string VTK_PARALLEL_IMAGE_NAME(); // DEFAULT_BASE_NAME.vtk.parallel.image + static std::string VTK_POLYDATA_NAME(); // DEFAULT_BASE_NAME.vtk.polydata + static std::string VTK_POLYDATA_LEGACY_NAME(); // DEFAULT_BASE_NAME.vtk.polydata.legacy + static std::string VTK_PARALLEL_POLYDATA_NAME(); // DEFAULT_BASE_NAME.vtk.parallel.polydata + + // ------------------------- Image formats (ITK based) -------------------------- + + static CustomMimeType NRRD_MIMETYPE(); // nrrd, nhdr + static CustomMimeType NIFTI_MIMETYPE(); + static CustomMimeType RAW_MIMETYPE(); // raw + + static std::string NRRD_MIMETYPE_NAME(); // DEFAULT_BASE_NAME.nrrd + static std::string NIFTI_MIMETYPE_NAME(); + static std::string RAW_MIMETYPE_NAME(); // DEFAULT_BASE_NAME.raw + + // ------------------------------ MITK formats ---------------------------------- + + static CustomMimeType POINTSET_MIMETYPE(); // mps + + static std::string POINTSET_MIMETYPE_NAME(); // DEFAULT_BASE_NAME.pointset + +private: + + // purposely not implemented + IOMimeTypes(); + IOMimeTypes(const IOMimeTypes&); +}; + +} + +#endif // MITKIOMIMETYPES_H diff --git a/Core/Code/IO/mitkIOUtil.cpp b/Core/Code/IO/mitkIOUtil.cpp index 35b16e1bdd..cbe827b419 100644 --- a/Core/Code/IO/mitkIOUtil.cpp +++ b/Core/Code/IO/mitkIOUtil.cpp @@ -1,1072 +1,1070 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkIOUtil.h" #include #include #include #include #include #include #include #include #include #include #include #include //ITK #include //VTK #include #include #include #include #include static std::string GetLastErrorStr() { #ifdef US_PLATFORM_POSIX return std::string(strerror(errno)); #else // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); std::string errMsg((LPCTSTR)lpMsgBuf); LocalFree(lpMsgBuf); return errMsg; #endif } #ifdef US_PLATFORM_WINDOWS #include #include // make the posix flags point to the obsolte bsd types on windows #define S_IRUSR S_IREAD #define S_IWUSR S_IWRITE #else #include #include #include #endif #include #include static const char validLetters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // A cross-platform version of the mkstemps function static int mkstemps_compat(char* tmpl, int suffixlen) { static unsigned long long value = 0; int savedErrno = errno; // Lower bound on the number of temporary files to attempt to generate. #define ATTEMPTS_MIN (62 * 62 * 62) /* The number of times to attempt to generate a temporary file. To conform to POSIX, this must be no smaller than TMP_MAX. */ #if ATTEMPTS_MIN < TMP_MAX const unsigned int attempts = TMP_MAX; #else const unsigned int attempts = ATTEMPTS_MIN; #endif const int len = strlen(tmpl); if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) { errno = EINVAL; return -1; } /* This is where the Xs start. */ char* XXXXXX = &tmpl[len - 6 - suffixlen]; /* Get some more or less random data. */ #ifdef US_PLATFORM_WINDOWS { SYSTEMTIME stNow; FILETIME ftNow; // get system time GetSystemTime(&stNow); stNow.wMilliseconds = 500; if (!SystemTimeToFileTime(&stNow, &ftNow)) { errno = -1; return -1; } unsigned long long randomTimeBits = ((static_cast(ftNow.dwHighDateTime) << 32) | static_cast(ftNow.dwLowDateTime)); value = randomTimeBits ^ static_cast(GetCurrentThreadId()); } #else { struct timeval tv; gettimeofday(&tv, NULL); unsigned long long randomTimeBits = ((static_cast(tv.tv_usec) << 32) | static_cast(tv.tv_sec)); value = randomTimeBits ^ static_cast(getpid()); } #endif for (unsigned int count = 0; count < attempts; value += 7777, ++count) { unsigned long long v = value; /* Fill in the random bits. */ XXXXXX[0] = validLetters[v % 62]; v /= 62; XXXXXX[1] = validLetters[v % 62]; v /= 62; XXXXXX[2] = validLetters[v % 62]; v /= 62; XXXXXX[3] = validLetters[v % 62]; v /= 62; XXXXXX[4] = validLetters[v % 62]; v /= 62; XXXXXX[5] = validLetters[v % 62]; int fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (fd >= 0) { errno = savedErrno; return fd; } else if (errno != EEXIST) { return -1; } } /* We got out of the loop because we ran out of combinations to try. */ errno = EEXIST; return -1; } // A cross-platform version of the POSIX mkdtemp function static char* mkdtemps_compat(char* tmpl, int suffixlen) { static unsigned long long value = 0; int savedErrno = errno; // Lower bound on the number of temporary dirs to attempt to generate. #define ATTEMPTS_MIN (62 * 62 * 62) /* The number of times to attempt to generate a temporary dir. To conform to POSIX, this must be no smaller than TMP_MAX. */ #if ATTEMPTS_MIN < TMP_MAX const unsigned int attempts = TMP_MAX; #else const unsigned int attempts = ATTEMPTS_MIN; #endif const int len = strlen(tmpl); if ((len - suffixlen) < 6 || strncmp(&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) { errno = EINVAL; return NULL; } /* This is where the Xs start. */ char* XXXXXX = &tmpl[len - 6 - suffixlen]; /* Get some more or less random data. */ #ifdef US_PLATFORM_WINDOWS { SYSTEMTIME stNow; FILETIME ftNow; // get system time GetSystemTime(&stNow); stNow.wMilliseconds = 500; if (!SystemTimeToFileTime(&stNow, &ftNow)) { errno = -1; return NULL; } unsigned long long randomTimeBits = ((static_cast(ftNow.dwHighDateTime) << 32) | static_cast(ftNow.dwLowDateTime)); value = randomTimeBits ^ static_cast(GetCurrentThreadId()); } #else { struct timeval tv; gettimeofday(&tv, NULL); unsigned long long randomTimeBits = ((static_cast(tv.tv_usec) << 32) | static_cast(tv.tv_sec)); value = randomTimeBits ^ static_cast(getpid()); } #endif unsigned int count = 0; for (; count < attempts; value += 7777, ++count) { unsigned long long v = value; /* Fill in the random bits. */ XXXXXX[0] = validLetters[v % 62]; v /= 62; XXXXXX[1] = validLetters[v % 62]; v /= 62; XXXXXX[2] = validLetters[v % 62]; v /= 62; XXXXXX[3] = validLetters[v % 62]; v /= 62; XXXXXX[4] = validLetters[v % 62]; v /= 62; XXXXXX[5] = validLetters[v % 62]; #ifdef US_PLATFORM_WINDOWS int fd = _mkdir (tmpl); //, _S_IREAD | _S_IWRITE | _S_IEXEC); #else int fd = mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); #endif if (fd >= 0) { errno = savedErrno; return tmpl; } else if (errno != EEXIST) { return NULL; } } /* We got out of the loop because we ran out of combinations to try. */ errno = EEXIST; return NULL; } //#endif //************************************************************** // mitk::IOUtil method definitions namespace mitk { const std::string IOUtil::DEFAULTIMAGEEXTENSION = ".nrrd"; const std::string IOUtil::DEFAULTSURFACEEXTENSION = ".stl"; const std::string IOUtil::DEFAULTPOINTSETEXTENSION = ".mps"; struct IOUtil::Impl { struct FixedReaderOptionsFunctor : public ReaderOptionsFunctorBase { FixedReaderOptionsFunctor(const IFileReader::Options& options) : m_Options(options) {} virtual bool operator()(LoadInfo& loadInfo) { IFileReader* reader = loadInfo.m_ReaderSelector.GetSelected().GetReader(); if (reader) { reader->SetOptions(m_Options); } return false; } private: const IFileReader::Options& m_Options; }; struct FixedWriterOptionsFunctor : public WriterOptionsFunctorBase { FixedWriterOptionsFunctor(const IFileReader::Options& options) : m_Options(options) {} virtual bool operator()(SaveInfo& saveInfo) { IFileWriter* writer = saveInfo.m_WriterSelector.GetSelected().GetWriter(); if (writer) { writer->SetOptions(m_Options); } return false; } private: const IFileWriter::Options& m_Options; }; static BaseData::Pointer LoadBaseDataFromFile(const std::string& path); static void SetDefaultDataNodeProperties(mitk::DataNode* node, const std::string& filePath = std::string()); }; #ifdef US_PLATFORM_WINDOWS std::string IOUtil::GetProgramPath() { char path[512]; std::size_t index = std::string(path, GetModuleFileName(NULL, path, 512)).find_last_of('\\'); return std::string(path, index); } #elif defined(US_PLATFORM_APPLE) #include std::string IOUtil::GetProgramPath() { char path[512]; uint32_t size = sizeof(path); if (_NSGetExecutablePath(path, &size) == 0) { std::size_t index = std::string(path).find_last_of('/'); std::string strPath = std::string(path, index); //const char* execPath = strPath.c_str(); //mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch(execPath,false); return strPath; } return std::string(); } #else #include #include #include std::string IOUtil::GetProgramPath() { std::stringstream ss; ss << "/proc/" << getpid() << "/exe"; char proc[512] = {0}; ssize_t ch = readlink(ss.str().c_str(), proc, 512); if (ch == -1) return std::string(); std::size_t index = std::string(proc).find_last_of('/'); return std::string(proc, index); } #endif char IOUtil::GetDirectorySeparator() { #ifdef US_PLATFORM_WINDOWS return '\\'; #else return '/'; #endif } std::string IOUtil::GetTempPath() { static std::string result; if (result.empty()) { #ifdef US_PLATFORM_WINDOWS char tempPathTestBuffer[1]; DWORD bufferLength = ::GetTempPath(1, tempPathTestBuffer); if (bufferLength == 0) { mitkThrow() << GetLastErrorStr(); } std::vector tempPath(bufferLength); bufferLength = ::GetTempPath(bufferLength, &tempPath[0]); if (bufferLength == 0) { mitkThrow() << GetLastErrorStr(); } result.assign(tempPath.begin(), tempPath.begin() + static_cast(bufferLength)); #else result = "/tmp/"; #endif } return result; } std::string IOUtil::CreateTemporaryFile(const std::string& templateName, std::string path) { ofstream tmpOutputStream; std::string returnValue = CreateTemporaryFile(tmpOutputStream,templateName,path); tmpOutputStream.close(); return returnValue; } std::string IOUtil::CreateTemporaryFile(std::ofstream& f, const std::string& templateName, std::string path) { return CreateTemporaryFile(f, std::ios_base::out | std::ios_base::trunc, templateName, path); } std::string IOUtil::CreateTemporaryFile(std::ofstream& f, std::ios_base::openmode mode, const std::string& templateName, std::string path) { if (path.empty()) { path = GetTempPath(); } path += GetDirectorySeparator() + templateName; std::vector dst_path(path.begin(), path.end()); dst_path.push_back('\0'); std::size_t lastX = path.find_last_of('X'); std::size_t firstX = path.find_last_not_of('X', lastX); int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; while (lastX != std::string::npos && (lastX - firstNonX) < 6) { lastX = path.find_last_of('X', firstX); firstX = path.find_last_not_of('X', lastX); firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; } std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1; int fd = mkstemps_compat(&dst_path[0], suffixlen); if(fd != -1) { path.assign(dst_path.begin(), dst_path.end() - 1); f.open(path.c_str(), mode | std::ios_base::out | std::ios_base::trunc); close(fd); } else { mitkThrow() << "Creating temporary file " << &dst_path[0] << " failed: " << GetLastErrorStr(); } return path; } std::string IOUtil::CreateTemporaryDirectory(const std::string& templateName, std::string path) { if (path.empty()) { path = GetTempPath(); } path += GetDirectorySeparator() + templateName; std::vector dst_path(path.begin(), path.end()); dst_path.push_back('\0'); std::size_t lastX = path.find_last_of('X'); std::size_t firstX = path.find_last_not_of('X', lastX); int firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; while (lastX != std::string::npos && (lastX - firstNonX) < 6) { lastX = path.find_last_of('X', firstX); firstX = path.find_last_not_of('X', lastX); firstNonX = firstX == std::string::npos ? - 1 : firstX - 1; } std::size_t suffixlen = lastX == std::string::npos ? path.size() : path.size() - lastX - 1; if(mkdtemps_compat(&dst_path[0], suffixlen) == NULL) { mitkThrow() << "Creating temporary directory " << &dst_path[0] << " failed: " << GetLastErrorStr(); } path.assign(dst_path.begin(), dst_path.end() - 1); return path; } DataStorage::SetOfObjects::Pointer IOUtil::Load(const std::string& path, DataStorage& storage) { std::vector paths; paths.push_back(path); return Load(paths, storage); } DataStorage::SetOfObjects::Pointer IOUtil::Load(const std::string& path, const IFileReader::Options& options, DataStorage& storage) { std::vector loadInfos; loadInfos.push_back(LoadInfo(path)); DataStorage::SetOfObjects::Pointer nodeResult = DataStorage::SetOfObjects::New(); Impl::FixedReaderOptionsFunctor optionsCallback(options); std::string errMsg = Load(loadInfos, nodeResult, &storage, &optionsCallback); if (!errMsg.empty()) { mitkThrow() << errMsg; } return nodeResult; } std::vector IOUtil::Load(const std::string& path) { std::vector paths; paths.push_back(path); return Load(paths); } std::vector IOUtil::Load(const std::string& path, const IFileReader::Options& options) { std::vector loadInfos; loadInfos.push_back(LoadInfo(path)); Impl::FixedReaderOptionsFunctor optionsCallback(options); std::string errMsg = Load(loadInfos, NULL, NULL, &optionsCallback); if (!errMsg.empty()) { mitkThrow() << errMsg; } return loadInfos.front().m_Output; } DataStorage::SetOfObjects::Pointer IOUtil::Load(const std::vector& paths, DataStorage& storage) { DataStorage::SetOfObjects::Pointer nodeResult = DataStorage::SetOfObjects::New(); std::vector loadInfos; for (std::vector::const_iterator iter = paths.begin(), iterEnd = paths.end(); iter != iterEnd; ++iter) { LoadInfo loadInfo(*iter); loadInfos.push_back(loadInfo); } std::string errMsg = Load(loadInfos, nodeResult, &storage, NULL); if (!errMsg.empty()) { mitkThrow() << errMsg; } return nodeResult; } std::vector IOUtil::Load(const std::vector& paths) { std::vector result; std::vector loadInfos; for (std::vector::const_iterator iter = paths.begin(), iterEnd = paths.end(); iter != iterEnd; ++iter) { LoadInfo loadInfo(*iter); loadInfos.push_back(loadInfo); } std::string errMsg = Load(loadInfos, NULL, NULL, NULL); if (!errMsg.empty()) { mitkThrow() << errMsg; } for (std::vector::const_iterator iter = loadInfos.begin(), iterEnd = loadInfos.end(); iter != iterEnd; ++iter) { result.insert(result.end(), iter->m_Output.begin(), iter->m_Output.end()); } return result; } int IOUtil::LoadFiles(const std::vector &fileNames, DataStorage& ds) { return static_cast(Load(fileNames, ds)->Size()); } DataStorage::Pointer IOUtil::LoadFiles(const std::vector& fileNames) { mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); Load(fileNames, *ds); return ds.GetPointer(); } BaseData::Pointer IOUtil::LoadBaseData(const std::string& path) { return Impl::LoadBaseDataFromFile(path); } BaseData::Pointer IOUtil::Impl::LoadBaseDataFromFile(const std::string& path) { std::vector baseDataList = Load(path); // The Load(path) call above should throw an exception if nothing could be loaded assert(!baseDataList.empty()); return baseDataList.front(); } DataNode::Pointer IOUtil::LoadDataNode(const std::string& path) { BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(baseData); Impl::SetDefaultDataNodeProperties(node, path); return node; } Image::Pointer IOUtil::LoadImage(const std::string& path) { BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path); mitk::Image::Pointer image = dynamic_cast(baseData.GetPointer()); if(image.IsNull()) { mitkThrow() << path << " is not a mitk::Image but a " << baseData->GetNameOfClass(); } return image; } Surface::Pointer IOUtil::LoadSurface(const std::string& path) { BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path); mitk::Surface::Pointer surface = dynamic_cast(baseData.GetPointer()); if(surface.IsNull()) { mitkThrow() << path << " is not a mitk::Surface but a " << baseData->GetNameOfClass(); } return surface; } PointSet::Pointer IOUtil::LoadPointSet(const std::string& path) { BaseData::Pointer baseData = Impl::LoadBaseDataFromFile(path); mitk::PointSet::Pointer pointset = dynamic_cast(baseData.GetPointer()); if(pointset.IsNull()) { mitkThrow() << path << " is not a mitk::PointSet but a " << baseData->GetNameOfClass(); } return pointset; } std::string IOUtil::Load(std::vector& loadInfos, DataStorage::SetOfObjects* nodeResult, DataStorage* ds, ReaderOptionsFunctorBase* optionsCallback) { if (loadInfos.empty()) { return "No input files given"; } int filesToRead = loadInfos.size(); mitk::ProgressBar::GetInstance()->AddStepsToDo(2*filesToRead); std::string errMsg; std::map usedReaderItems; for(std::vector::iterator infoIter = loadInfos.begin(), infoIterEnd = loadInfos.end(); infoIter != infoIterEnd; ++infoIter) { std::vector readers = infoIter->m_ReaderSelector.Get(); if (readers.empty()) { errMsg += "No reader available for '" + infoIter->m_Path + "'\n"; continue; } bool callOptionsCallback = readers.size() > 1 || !readers.front().GetReader()->GetOptions().empty(); // check if we already used a reader which should be re-used std::vector currMimeTypes = infoIter->m_ReaderSelector.GetMimeTypes(); std::string selectedMimeType; for (std::vector::const_iterator mimeTypeIter = currMimeTypes.begin(), mimeTypeIterEnd = currMimeTypes.end(); mimeTypeIter != mimeTypeIterEnd; ++mimeTypeIter) { std::map::const_iterator oldSelectedItemIter = usedReaderItems.find(mimeTypeIter->GetName()); if (oldSelectedItemIter != usedReaderItems.end()) { // we found an already used item for a mime-type which is contained // in the current reader set, check all current readers if there service // id equals the old reader for (std::vector::const_iterator currReaderItem = readers.begin(), currReaderItemEnd = readers.end(); currReaderItem != currReaderItemEnd; ++currReaderItem) { if (currReaderItem->GetMimeType().GetName() == mimeTypeIter->GetName() && currReaderItem->GetServiceId() == oldSelectedItemIter->second.GetServiceId() && currReaderItem->GetConfidenceLevel() >= oldSelectedItemIter->second.GetConfidenceLevel()) { // okay, we used the same reader already, re-use its options selectedMimeType = mimeTypeIter->GetName(); callOptionsCallback = false; infoIter->m_ReaderSelector.Select(oldSelectedItemIter->second.GetServiceId()); infoIter->m_ReaderSelector.GetSelected().GetReader()->SetOptions( oldSelectedItemIter->second.GetReader()->GetOptions()); break; } } if (!selectedMimeType.empty()) break; } } if (callOptionsCallback && optionsCallback) { callOptionsCallback = (*optionsCallback)(*infoIter); if (!callOptionsCallback && !infoIter->m_Cancel) { usedReaderItems.erase(selectedMimeType); FileReaderSelector::Item selectedItem = infoIter->m_ReaderSelector.GetSelected(); usedReaderItems.insert(std::make_pair(selectedItem.GetMimeType().GetName(), selectedItem)); } } if (infoIter->m_Cancel) { errMsg += "Reading operation(s) cancelled."; break; } IFileReader* reader = infoIter->m_ReaderSelector.GetSelected().GetReader(); if (reader == NULL) { errMsg += "Unexpected NULL reader."; break; } - MITK_INFO << "******* USING READER " << typeid(*reader).name() << "*********"; - // Do the actual reading try { DataStorage::SetOfObjects::Pointer nodes; if (ds != NULL) { nodes = reader->Read(*ds); } else { nodes = DataStorage::SetOfObjects::New(); std::vector baseData = reader->Read(); for (std::vector::iterator iter = baseData.begin(); iter != baseData.end(); ++iter) { if (iter->IsNotNull()) { mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(*iter); nodes->InsertElement(nodes->Size(), node); } } } for (DataStorage::SetOfObjects::ConstIterator nodeIter = nodes->Begin(), nodeIterEnd = nodes->End(); nodeIter != nodeIterEnd; ++nodeIter) { const mitk::DataNode::Pointer& node = nodeIter->Value(); mitk::BaseData::Pointer data = node->GetData(); if (data.IsNull()) { continue; } mitk::StringProperty::Pointer pathProp = mitk::StringProperty::New(infoIter->m_Path); data->SetProperty("path", pathProp); infoIter->m_Output.push_back(data); if (nodeResult) { nodeResult->push_back(nodeIter->Value()); } } if (infoIter->m_Output.empty() || (nodeResult && nodeResult->Size() == 0)) { errMsg += "Unknown read error occurred reading " + infoIter->m_Path; } } catch (const std::exception& e) { errMsg += "Exception occured when reading file " + infoIter->m_Path + ":\n" + e.what() + "\n\n"; } mitk::ProgressBar::GetInstance()->Progress(2); --filesToRead; } if (!errMsg.empty()) { MITK_ERROR << errMsg; } mitk::ProgressBar::GetInstance()->Progress(2*filesToRead); return errMsg; } void IOUtil::Save(const BaseData* data, const std::string& path) { Save(data, path, IFileWriter::Options()); } void IOUtil::Save(const BaseData* data, const std::string& path, const IFileWriter::Options& options) { Save(data, std::string(), path, options); } void IOUtil::Save(const BaseData* data, const std::string& mimeType, const std::string& path, bool addExtension) { Save(data, mimeType, path, IFileWriter::Options(), addExtension); } void IOUtil::Save(const BaseData* data, const std::string& mimeType, const std::string& path, const IFileWriter::Options& options, bool addExtension) { std::string errMsg; if (options.empty()) { errMsg = Save(data, mimeType, path, NULL, addExtension); } else { Impl::FixedWriterOptionsFunctor optionsCallback(options); errMsg = Save(data, mimeType, path, &optionsCallback, addExtension); } if (!errMsg.empty()) { mitkThrow() << errMsg; } } void IOUtil::Save(std::vector& saveInfos) { std::string errMsg = Save(saveInfos, NULL); if (!errMsg.empty()) { mitkThrow() << errMsg; } } bool IOUtil::SaveImage(mitk::Image::Pointer image, const std::string& path) { Save(image, path); return true; } bool IOUtil::SaveSurface(Surface::Pointer surface, const std::string& path) { Save(surface, path); return true; } bool IOUtil::SavePointSet(PointSet::Pointer pointset, const std::string& path) { Save(pointset, path); return true; } bool IOUtil::SaveBaseData( mitk::BaseData* data, const std::string& path) { Save(data, path); return true; } std::string IOUtil::Save(const BaseData* data, const std::string& mimeTypeName, const std::string& path, WriterOptionsFunctorBase* optionsCallback, bool addExtension) { if (path.empty()) { return "No output filename given"; } mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); MimeType mimeType = mimeTypeProvider->GetMimeTypeForName(mimeTypeName); SaveInfo saveInfo(data, mimeType, path); + std::string ext = itksys::SystemTools::GetFilenameExtension(path); + if (saveInfo.m_WriterSelector.IsEmpty()) { - return std::string("No writer registered for type ") + data->GetNameOfClass() + - (mimeType.IsValid() ? (std::string(" and mime-type ") + mimeType.GetName()) : std::string()); + return std::string("No suitable writer found for the current data of type ") + data->GetNameOfClass() + + (mimeType.IsValid() ? (std::string(" and mime-type ") + mimeType.GetName()) : std::string()) + + (ext.empty() ? std::string() : (std::string(" with extension ") + ext)); } // Add an extension if not already specified - std::string ext = itksys::SystemTools::GetFilenameExtension(path); if (ext.empty() && addExtension) { ext = saveInfo.m_MimeType.GetExtensions().empty() ? std::string() : "." + saveInfo.m_MimeType.GetExtensions().front(); } std::vector infos; infos.push_back(saveInfo); return Save(infos, optionsCallback); } std::string IOUtil::Save(std::vector& saveInfos, WriterOptionsFunctorBase* optionsCallback) { if (saveInfos.empty()) { return "No data for saving available"; } int filesToWrite = saveInfos.size(); mitk::ProgressBar::GetInstance()->AddStepsToDo(2*filesToWrite); std::string errMsg; std::set usedSaveInfos; for (std::vector::iterator infoIter = saveInfos.begin(), infoIterEnd = saveInfos.end(); infoIter != infoIterEnd; ++infoIter) { const std::string baseDataType = infoIter->m_BaseData->GetNameOfClass(); std::vector writers = infoIter->m_WriterSelector.Get(); // Error out if no compatible Writer was found if (writers.empty()) { errMsg += std::string("No writer available for ") + baseDataType + " data.\n"; continue; } bool callOptionsCallback = writers.size() > 1 || !writers[0].GetWriter()->GetOptions().empty(); // check if we already used a writer for this base data type // which should be re-used std::set::const_iterator oldSaveInfoIter = usedSaveInfos.find(*infoIter); if (oldSaveInfoIter != usedSaveInfos.end()) { // we previously saved a base data object of the same data with the same mime-type, // check if the same writer is contained in the current writer set and if the // confidence level matches FileWriterSelector::Item oldSelectedItem = oldSaveInfoIter->m_WriterSelector.Get(oldSaveInfoIter->m_WriterSelector.GetSelectedId()); for (std::vector::const_iterator currWriterItem = writers.begin(), currWriterItemEnd = writers.end(); currWriterItem != currWriterItemEnd; ++currWriterItem) { if (currWriterItem->GetServiceId() == oldSelectedItem.GetServiceId() && currWriterItem->GetConfidenceLevel() >= oldSelectedItem.GetConfidenceLevel()) { // okay, we used the same writer already, re-use its options callOptionsCallback = false; infoIter->m_WriterSelector.Select(oldSaveInfoIter->m_WriterSelector.GetSelectedId()); infoIter->m_WriterSelector.GetSelected().GetWriter()->SetOptions( oldSelectedItem.GetWriter()->GetOptions()); break; } } } if (callOptionsCallback && optionsCallback) { callOptionsCallback = (*optionsCallback)(*infoIter); if (!callOptionsCallback && !infoIter->m_Cancel) { usedSaveInfos.erase(*infoIter); usedSaveInfos.insert(*infoIter); } } if (infoIter->m_Cancel) { errMsg += "Writing operation(s) cancelled."; break; } IFileWriter* writer = infoIter->m_WriterSelector.GetSelected().GetWriter(); if (writer == NULL) { errMsg += "Unexpected NULL writer."; break; } - MITK_INFO << "******* USING WRITER " << typeid(*writer).name() << "*********"; - // Do the actual writing try { writer->SetOutputLocation(infoIter->m_Path); writer->Write(); } catch(const std::exception& e) { errMsg += std::string("Exception occurred when writing to ") + infoIter->m_Path + ":\n" + e.what() + "\n"; } mitk::ProgressBar::GetInstance()->Progress(2); --filesToWrite; } if (!errMsg.empty()) { MITK_ERROR << errMsg; } mitk::ProgressBar::GetInstance()->Progress(2*filesToWrite); return errMsg; } // This method can be removed after the deprecated LoadDataNode() method was removed void IOUtil::Impl::SetDefaultDataNodeProperties(DataNode* node, const std::string& filePath) { // path mitk::StringProperty::Pointer pathProp = mitk::StringProperty::New( itksys::SystemTools::GetFilenamePath(filePath) ); node->SetProperty(StringProperty::PATH, pathProp); // name already defined? mitk::StringProperty::Pointer nameProp = dynamic_cast(node->GetProperty("name")); if(nameProp.IsNull() || (strcmp(nameProp->GetValue(),"No Name!")==0)) { // name already defined in BaseData mitk::StringProperty::Pointer baseDataNameProp = dynamic_cast(node->GetData()->GetProperty("name").GetPointer() ); if(baseDataNameProp.IsNull() || (strcmp(baseDataNameProp->GetValue(),"No Name!")==0)) { // name neither defined in node, nor in BaseData -> name = filename nameProp = mitk::StringProperty::New( itksys::SystemTools::GetFilenameWithoutExtension(filePath)); node->SetProperty("name", nameProp); } else { // name defined in BaseData! nameProp = mitk::StringProperty::New(baseDataNameProp->GetValue()); node->SetProperty("name", nameProp); } } // visibility if(!node->GetProperty("visible")) { node->SetVisibility(true); } } IOUtil::SaveInfo::SaveInfo(const BaseData* baseData, const MimeType& mimeType, const std::string& path) : m_BaseData(baseData) , m_WriterSelector(baseData, mimeType.GetName(), path) , m_MimeType(mimeType.IsValid() ? mimeType // use the original mime-type : (m_WriterSelector.IsEmpty() ? mimeType // no writer found, use the original invalid mime-type : m_WriterSelector.GetDefault().GetMimeType() // use the found default mime-type ) ) , m_Path(path) , m_Cancel(false) { } bool IOUtil::SaveInfo::operator<(const IOUtil::SaveInfo& other) const { int r = strcmp(m_BaseData->GetNameOfClass(), other.m_BaseData->GetNameOfClass()); if (r == 0) { return m_WriterSelector.GetSelected().GetMimeType() < other.m_WriterSelector.GetSelected().GetMimeType(); } return r < 0; } IOUtil::LoadInfo::LoadInfo(const std::string& path) : m_Path(path) , m_ReaderSelector(path) , m_Cancel(false) { } } diff --git a/Core/Code/Internal/mitkCoreActivator.cpp b/Core/Code/Internal/mitkCoreActivator.cpp index 8f995dde2e..475df003e3 100644 --- a/Core/Code/Internal/mitkCoreActivator.cpp +++ b/Core/Code/Internal/mitkCoreActivator.cpp @@ -1,408 +1,443 @@ /*=================================================================== 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 +#include +#include +#include +#include +#include #include #include "mitkLegacyFileWriterService.h" +#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; }; +class FixedNiftiImageIO : public itk::NiftiImageIO +{ +public: + + /** Standard class typedefs. */ + typedef FixedNiftiImageIO Self; + typedef itk::NiftiImageIO Superclass; + typedef itk::SmartPointer< Self > Pointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self) + + /** Run-time type information (and related methods). */ + itkTypeMacro(FixedNiftiImageIO, Superclass) + + virtual bool SupportsDimension(unsigned long dim) + { + return dim > 1 && dim < 5; + } + +}; 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->RegisterDefaultMimeTypes(); this->RegisterItkReaderWriter(); + this->RegisterVtkReaderWriter(); // 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(); */ this->RegisterLegacyWriter(); } 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; } for(std::vector::iterator iter = m_LegacyWriters.begin(), endIter = m_LegacyWriters.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::RegisterDefaultMimeTypes() { // Register some default mime-types - // Custom MITK point set format - mitk::CustomMimeType pointSetMimeType("application/vnd.mitk.pointset"); - pointSetMimeType.AddExtension("mps"); - pointSetMimeType.SetCategory("Point Sets"); - pointSetMimeType.SetComment("MITK Point Set"); - m_DefaultMimeTypes.push_back(pointSetMimeType); - m_Context->RegisterService(&m_DefaultMimeTypes.back()); - - // Register the NRRD format early on - mitk::CustomMimeType nrrdMimeType("application/vnd.mitk.nrrd"); - nrrdMimeType.AddExtension("nrrd"); - nrrdMimeType.AddExtension("nhdr"); - nrrdMimeType.SetCategory("Images"); - nrrdMimeType.SetComment("NRRD"); - m_DefaultMimeTypes.push_back(nrrdMimeType); - m_Context->RegisterService(&m_DefaultMimeTypes.back()); + std::vector mimeTypes = mitk::IOMimeTypes::Get(); + for (std::vector::const_iterator mimeTypeIter = mimeTypes.begin(), + iterEnd = mimeTypes.end(); mimeTypeIter != iterEnd; ++mimeTypeIter) + { + m_DefaultMimeTypes.push_back(*mimeTypeIter); + m_Context->RegisterService(&m_DefaultMimeTypes.back()); + } } void MitkCoreActivator::RegisterItkReaderWriter() { 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()); + + // NiftiImageIO does not provide a correct "SupportsDimension()" methods + // and the supported read/write extensions are not ordered correctly + if (dynamic_cast(io)) continue; + if (io) { m_FileIOs.push_back(new mitk::ItkImageIO(io)); } else { MITK_WARN << "Error ImageIO factory did not return an ImageIOBase: " << ( *i )->GetNameOfClass(); } } + + mitk::ItkImageIO* io = new mitk::ItkImageIO(mitk::CustomMimeType(mitk::IOMimeTypes::NIFTI_MIMETYPE_NAME()), + new FixedNiftiImageIO(), 0); + m_FileIOs.push_back(io); +} + +void MitkCoreActivator::RegisterVtkReaderWriter() +{ + m_FileIOs.push_back(new mitk::SurfaceVtkXmlIO()); + m_FileIOs.push_back(new mitk::SurfaceStlIO()); + m_FileIOs.push_back(new mitk::SurfaceVtkLegacyIO()); + + m_FileIOs.push_back(new mitk::ImageVtkXmlIO()); + m_FileIOs.push_back(new mitk::ImageVtkLegacyIO()); } void MitkCoreActivator::RegisterLegacyWriter() { std::list allobjects = itk::ObjectFactoryBase::CreateAllInstance("IOWriter"); for( std::list::iterator i = allobjects.begin(); i != allobjects.end(); ++i) { mitk::FileWriter::Pointer io = dynamic_cast(i->GetPointer()); if(io) { std::string description = std::string("Legacy ") + io->GetNameOfClass() + " Reader"; mitk::IFileWriter* writer = new mitk::LegacyFileWriterService(io, description); m_LegacyWriters.push_back(writer); } else { MITK_ERROR << "Error IOWriter override is not of type mitk::FileWriter: " << (*i)->GetNameOfClass() << std::endl; } } } 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 3d72d10189..2e47d4e9ce 100644 --- a/Core/Code/Internal/mitkCoreActivator.h +++ b/Core/Code/Internal/mitkCoreActivator.h @@ -1,86 +1,87 @@ /*=================================================================== 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 // 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 RegisterDefaultMimeTypes(); void RegisterItkReaderWriter(); + void RegisterVtkReaderWriter(); void RegisterLegacyWriter(); 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; std::vector m_LegacyWriters; std::vector m_DefaultMimeTypes; us::ServiceRegistration m_MimeTypeProviderReg; us::ModuleContext* m_Context; }; #endif // MITKCOREACTIVATOR_H_ diff --git a/Core/Code/Internal/mitkFileReaderWriterBase.cpp b/Core/Code/Internal/mitkFileReaderWriterBase.cpp index 734f0f0a6b..cf0eb215f7 100644 --- a/Core/Code/Internal/mitkFileReaderWriterBase.cpp +++ b/Core/Code/Internal/mitkFileReaderWriterBase.cpp @@ -1,221 +1,261 @@ /*=================================================================== 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 "mitkIOMimeTypes.h" #include #include namespace mitk { FileReaderWriterBase::FileReaderWriterBase() : m_Ranking(0) - , m_MimeTypePrefix("application/vnd.mitk.") + , m_MimeTypePrefix(IOMimeTypes::DEFAULT_BASE_NAME() + ".") { } FileReaderWriterBase::~FileReaderWriterBase() { this->UnregisterMimeType(); } FileReaderWriterBase::FileReaderWriterBase(const FileReaderWriterBase& other) : m_Description(other.m_Description) , m_Ranking(other.m_Ranking) , m_MimeTypePrefix(other.m_MimeTypePrefix) , m_Options(other.m_Options) , m_DefaultOptions(other.m_DefaultOptions) , m_CustomMimeType(other.m_CustomMimeType) { } 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 CustomMimeType& mimeType) { m_CustomMimeType = mimeType; } CustomMimeType FileReaderWriterBase::GetMimeType() const { return m_CustomMimeType; } -CustomMimeType&FileReaderWriterBase::GetMimeType() +CustomMimeType& FileReaderWriterBase::GetMimeType() { return m_CustomMimeType; } +MimeType FileReaderWriterBase::GetRegisteredMimeType() const +{ + MimeType result; + if (!m_MimeTypeReg) + { + if (!m_CustomMimeType.GetName().empty()) + { + CoreServicePointer mimeTypeProvider( + CoreServices::GetMimeTypeProvider(us::GetModuleContext())); + return mimeTypeProvider->GetMimeTypeForName(m_CustomMimeType.GetName()); + } + return result; + } + + us::ServiceReferenceU reference = m_MimeTypeReg.GetReference(); + try + { + int rank = 0; + us::Any rankProp = reference.GetProperty(us::ServiceConstants::SERVICE_RANKING()); + if (!rankProp.Empty()) + { + rank = us::any_cast(rankProp); + } + long id = us::any_cast(reference.GetProperty(us::ServiceConstants::SERVICE_ID())); + result = MimeType(m_CustomMimeType, rank, id); + } + catch (const us::BadAnyCastException& e) + { + MITK_WARN << "Unexpected exception: " << e.what(); + } + return result; +} + void FileReaderWriterBase::SetMimeTypePrefix(const std::string& prefix) { m_MimeTypePrefix = prefix; } std::string FileReaderWriterBase::GetMimeTypePrefix() const { return m_MimeTypePrefix; } void FileReaderWriterBase::SetDescription(const std::string& description) { m_Description = description; } std::string FileReaderWriterBase::GetDescription() const { return m_Description; } 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."); CoreServicePointer mimeTypeProvider(CoreServices::GetMimeTypeProvider(context)); const std::vector extensions = m_CustomMimeType.GetExtensions(); // If the mime type name 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 (!m_CustomMimeType.GetName().empty() && extensions.empty()) { if(!mimeTypeProvider->GetMimeTypeForName(m_CustomMimeType.GetName()).IsValid()) { MITK_WARN << "Registering a MITK reader or writer with an unknown MIME type " << m_CustomMimeType.GetName(); } return m_MimeTypeReg; } - // If the mime type name is empty, get a mime type using the extensions list + // If the mime type name and extensions list is empty, print a warning if(m_CustomMimeType.GetName().empty() && extensions.empty()) { MITK_WARN << "Trying to register a MITK reader or writer with an empty mime type name and empty extension list."; return m_MimeTypeReg; } - // extensions is not empty, so register a mime-type + // extensions is not empty + if(m_CustomMimeType.GetName().empty()) { - // Register a new mime type by creating a synthetic mime type name from the + // Create a synthetic mime type name from the // first extension in the list m_CustomMimeType.SetName(m_MimeTypePrefix + extensions.front()); } + + // Register a new mime type + //us::ServiceProperties props; + //props["name"] = m_CustomMimeType.GetName(); + //props["extensions"] = m_CustomMimeType.GetExtensions(); m_MimeTypeReg = context->RegisterService(&m_CustomMimeType); return m_MimeTypeReg; } void FileReaderWriterBase::UnregisterMimeType() { if (m_MimeTypeReg) { try { m_MimeTypeReg.Unregister(); } catch (const std::logic_error&) { // service already unregistered } } } } diff --git a/Core/Code/Internal/mitkFileReaderWriterBase.h b/Core/Code/Internal/mitkFileReaderWriterBase.h index 33e644b2d2..90d614cf00 100644 --- a/Core/Code/Internal/mitkFileReaderWriterBase.h +++ b/Core/Code/Internal/mitkFileReaderWriterBase.h @@ -1,111 +1,113 @@ /*=================================================================== 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 MITKFILEREADERWRITERBASE_H #define MITKFILEREADERWRITERBASE_H #include #include #include #include #include namespace mitk { class FileReaderWriterBase { public: typedef std::map Options; typedef mitk::MessageAbstractDelegate1 ProgressCallback; FileReaderWriterBase(); ~FileReaderWriterBase(); Options GetOptions() const; us::Any GetOption(const std::string &name) const; void SetOptions(const Options& options); void SetOption(const std::string& name, const us::Any& value); 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; void SetMimeType(const CustomMimeType& mimeType); CustomMimeType GetMimeType() const; CustomMimeType& GetMimeType(); + MimeType GetRegisteredMimeType() const; + void SetMimeTypePrefix(const std::string& prefix); std::string GetMimeTypePrefix() const; void SetDescription(const std::string& description); std::string GetDescription() const; void AddProgressCallback(const ProgressCallback& callback); void RemoveProgressCallback(const ProgressCallback& callback); us::ServiceRegistration RegisterMimeType(us::ModuleContext* context); void UnregisterMimeType(); protected: FileReaderWriterBase(const FileReaderWriterBase& other); std::string m_Description; int m_Ranking; std::string m_MimeTypePrefix; /** * \brief Options supported by this reader. Set sensible default values! * * Can be left emtpy if no special options are required. */ Options m_Options; Options m_DefaultOptions; //us::PrototypeServiceFactory* m_PrototypeFactory; Message1 m_ProgressMessage; CustomMimeType m_CustomMimeType; us::ServiceRegistration m_MimeTypeReg; private: // purposely not implemented FileReaderWriterBase& operator=(const FileReaderWriterBase& other); }; } #endif // MITKFILEREADERWRITERBASE_H diff --git a/Core/Code/Internal/mitkImageVtkLegacyIO.cpp b/Core/Code/Internal/mitkImageVtkLegacyIO.cpp new file mode 100644 index 0000000000..4ceb996638 --- /dev/null +++ b/Core/Code/Internal/mitkImageVtkLegacyIO.cpp @@ -0,0 +1,107 @@ +/*=================================================================== + +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 "mitkImageVtkLegacyIO.h" + +#include "mitkImage.h" +#include "mitkIOMimeTypes.h" +#include "mitkImageVtkReadAccessor.h" + +#include +#include +#include +#include +#include + +namespace mitk { + +ImageVtkLegacyIO::ImageVtkLegacyIO() + : AbstractFileIO(Image::GetStaticNameOfClass(), IOMimeTypes::VTK_IMAGE_MIMETYPE(), "VTK XML Image") +{ + this->RegisterService(); +} + +std::vector ImageVtkLegacyIO::Read() +{ + // The legay vtk reader cannot work with input streams + const std::string fileName = this->GetLocalFileName(); + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(fileName.c_str()); + reader->Update(); + + if ( reader->GetOutput() != NULL ) + { + mitk::Image::Pointer output = mitk::Image::New(); + output->Initialize(reader->GetOutput()); + output->SetVolume(reader->GetOutput()->GetScalarPointer()); + std::vector result; + result.push_back(output.GetPointer()); + return result; + } + else + { + mitkThrow() << "vtkStructuredPointsReader error: " << vtkErrorCode::GetStringFromErrorCode(reader->GetErrorCode()); + } +} + +IFileIO::ConfidenceLevel ImageVtkLegacyIO::GetReaderConfidenceLevel() const +{ + if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(this->GetLocalFileName().c_str()); + if (reader->IsFileStructuredPoints()) + { + return Supported; + } + return Unsupported; +} + +void ImageVtkLegacyIO::Write() +{ + ValidateOutputLocation(); + + const Image* input = dynamic_cast(this->GetInput()); + + vtkSmartPointer writer = vtkSmartPointer::New(); + + // The legacy vtk image writer cannot write to streams + LocalFile localFile(this); + writer->SetFileName(localFile.GetFileName().c_str()); + + ImageVtkReadAccessor vtkReadAccessor(Image::ConstPointer(input), NULL, NULL); + writer->SetInputData(const_cast(vtkReadAccessor.GetVtkImageData())); + + if (writer->Write() == 0 || writer->GetErrorCode() != 0 ) + { + mitkThrow() << "vtkStructuredPointesWriter error: " << vtkErrorCode::GetStringFromErrorCode(writer->GetErrorCode()); + } +} + +IFileIO::ConfidenceLevel ImageVtkLegacyIO::GetWriterConfidenceLevel() const +{ + if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported; + const Image* input = static_cast(this->GetInput()); + if (input->GetDimension() == 3) return Supported; + else if (input->GetDimension() < 3) return PartiallySupported; + return Unsupported; +} + +ImageVtkLegacyIO* ImageVtkLegacyIO::IOClone() const +{ + return new ImageVtkLegacyIO(*this); +} + +} diff --git a/Core/Code/Internal/mitkItkImageIO.h b/Core/Code/Internal/mitkImageVtkLegacyIO.h similarity index 60% copy from Core/Code/Internal/mitkItkImageIO.h copy to Core/Code/Internal/mitkImageVtkLegacyIO.h index db0bd4aeb3..6d4c81e2ec 100644 --- a/Core/Code/Internal/mitkItkImageIO.h +++ b/Core/Code/Internal/mitkImageVtkLegacyIO.h @@ -1,61 +1,50 @@ /*=================================================================== 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 MITKITKFILEIO_H -#define MITKITKFILEIO_H +#ifndef MITKIMAGEVTKLEGACYIO_H +#define MITKIMAGEVTKLEGACYIO_H #include "mitkAbstractFileIO.h" -#include - namespace mitk { -// This class wraps ITK image IO objects registered via the -// ITK object factory system -class ItkImageIO : public AbstractFileIO +class ImageVtkLegacyIO : public mitk::AbstractFileIO { public: - ItkImageIO(itk::ImageIOBase::Pointer imageIO); + ImageVtkLegacyIO(); // -------------- AbstractFileReader ------------- using AbstractFileReader::Read; - virtual std::vector > Read(); + virtual std::vector Read(); virtual ConfidenceLevel GetReaderConfidenceLevel() const; // -------------- AbstractFileWriter ------------- virtual void Write(); + virtual ConfidenceLevel GetWriterConfidenceLevel() const; private: - ItkImageIO(const ItkImageIO& other); - - ItkImageIO* IOClone() const; - - std::vector FixUpImageIOExtensions(const std::string& imageIOName); - - itk::ImageIOBase::Pointer m_ImageIO; + ImageVtkLegacyIO* IOClone() const; }; -} // namespace mitk - -#endif /* MITKITKFILEIO_H */ +} +#endif // MITKIMAGEVTKLEGACYIO_H diff --git a/Core/Code/Internal/mitkImageVtkXmlIO.cpp b/Core/Code/Internal/mitkImageVtkXmlIO.cpp new file mode 100644 index 0000000000..cb8c35da10 --- /dev/null +++ b/Core/Code/Internal/mitkImageVtkXmlIO.cpp @@ -0,0 +1,142 @@ +/*=================================================================== + +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 "mitkImageVtkXmlIO.h" + +#include "mitkImage.h" +#include "mitkIOMimeTypes.h" +#include "mitkImageVtkReadAccessor.h" + +#include +#include +#include +#include +#include + +namespace mitk { + +class VtkXMLImageDataReader : public ::vtkXMLImageDataReader +{ +public: + static VtkXMLImageDataReader *New() { return new VtkXMLImageDataReader(); } + vtkTypeMacro(VtkXMLImageDataReader,vtkXMLImageDataReader) + + void SetStream(std::istream* is) { this->Stream = is; } + std::istream* GetStream() const { return this->Stream; } +}; + +class VtkXMLImageDataWriter : public ::vtkXMLImageDataWriter +{ +public: + static VtkXMLImageDataWriter *New() { return new VtkXMLImageDataWriter(); } + vtkTypeMacro(VtkXMLImageDataWriter,vtkXMLImageDataWriter) + + void SetStream(std::ostream* os) { this->Stream = os; } + std::ostream* GetStream() const { return this->Stream; } +}; + +ImageVtkXmlIO::ImageVtkXmlIO() + : AbstractFileIO(Image::GetStaticNameOfClass(), IOMimeTypes::VTK_IMAGE_MIMETYPE(), "VTK XML Image") +{ + this->RegisterService(); +} + +std::vector ImageVtkXmlIO::Read() +{ + vtkSmartPointer reader = vtkSmartPointer::New(); + if (this->GetInputStream()) + { + reader->SetStream(this->GetInputStream()); + } + else + { + reader->SetFileName(this->GetInputLocation().c_str()); + } + reader->Update(); + + if (reader->GetOutput() != NULL) + { + mitk::Image::Pointer output = mitk::Image::New(); + output->Initialize(reader->GetOutput()); + output->SetVolume(reader->GetOutput()->GetScalarPointer()); + std::vector result; + result.push_back(output.GetPointer()); + return result; + } + else + { + mitkThrow() << "vtkXMLImageDataReader error: " << vtkErrorCode::GetStringFromErrorCode(reader->GetErrorCode()); + } +} + +IFileIO::ConfidenceLevel ImageVtkXmlIO::GetReaderConfidenceLevel() const +{ + if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; + if (this->GetInputStream() == NULL) + { + // check if the xml vtk reader can handle the file + vtkSmartPointer xmlReader = vtkSmartPointer::New(); + if (xmlReader->CanReadFile(this->GetInputLocation().c_str()) != 0) + { + return Supported; + } + return Unsupported; + } + // in case of an input stream, VTK does not seem to have methods for + // validating it + return Supported; +} + +void ImageVtkXmlIO::Write() +{ + ValidateOutputLocation(); + + const Image* input = dynamic_cast(this->GetInput()); + + vtkSmartPointer writer = vtkSmartPointer::New(); + if (this->GetOutputStream()) + { + writer->SetStream(this->GetOutputStream()); + } + else + { + writer->SetFileName(this->GetOutputLocation().c_str()); + } + + ImageVtkReadAccessor vtkReadAccessor(Image::ConstPointer(input), NULL, NULL); + writer->SetInputData(const_cast(vtkReadAccessor.GetVtkImageData())); + + if (writer->Write() == 0 || writer->GetErrorCode() != 0 ) + { + mitkThrow() << "vtkXMLImageDataWriter error: " << vtkErrorCode::GetStringFromErrorCode(writer->GetErrorCode()); + } +} + +IFileIO::ConfidenceLevel ImageVtkXmlIO::GetWriterConfidenceLevel() const +{ + if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported; + const Image* input = static_cast(this->GetInput()); + if (input->GetDimension() == 3) return Supported; + else if (input->GetDimension() < 3) return PartiallySupported; + return Unsupported; +} + +ImageVtkXmlIO* ImageVtkXmlIO::IOClone() const +{ + return new ImageVtkXmlIO(*this); +} + +} diff --git a/Core/Code/Internal/mitkItkImageIO.h b/Core/Code/Internal/mitkImageVtkXmlIO.h similarity index 60% copy from Core/Code/Internal/mitkItkImageIO.h copy to Core/Code/Internal/mitkImageVtkXmlIO.h index db0bd4aeb3..4463a5326d 100644 --- a/Core/Code/Internal/mitkItkImageIO.h +++ b/Core/Code/Internal/mitkImageVtkXmlIO.h @@ -1,61 +1,50 @@ /*=================================================================== 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 MITKITKFILEIO_H -#define MITKITKFILEIO_H +#ifndef MITKIMAGEVTKXMLIO_H +#define MITKIMAGEVTKXMLIO_H #include "mitkAbstractFileIO.h" -#include - namespace mitk { -// This class wraps ITK image IO objects registered via the -// ITK object factory system -class ItkImageIO : public AbstractFileIO +class ImageVtkXmlIO : public mitk::AbstractFileIO { public: - ItkImageIO(itk::ImageIOBase::Pointer imageIO); + ImageVtkXmlIO(); // -------------- AbstractFileReader ------------- using AbstractFileReader::Read; - virtual std::vector > Read(); + virtual std::vector Read(); virtual ConfidenceLevel GetReaderConfidenceLevel() const; // -------------- AbstractFileWriter ------------- virtual void Write(); + virtual ConfidenceLevel GetWriterConfidenceLevel() const; private: - ItkImageIO(const ItkImageIO& other); - - ItkImageIO* IOClone() const; - - std::vector FixUpImageIOExtensions(const std::string& imageIOName); - - itk::ImageIOBase::Pointer m_ImageIO; + ImageVtkXmlIO* IOClone() const; }; -} // namespace mitk - -#endif /* MITKITKFILEIO_H */ +} +#endif // MITKIMAGEVTKXMLIO_H diff --git a/Core/Code/Internal/mitkItkImageIO.cpp b/Core/Code/Internal/mitkItkImageIO.cpp index 7be32ead8c..9b0d437e40 100644 --- a/Core/Code/Internal/mitkItkImageIO.cpp +++ b/Core/Code/Internal/mitkItkImageIO.cpp @@ -1,483 +1,503 @@ /*=================================================================== 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 "mitkItkImageIO.h" #include #include #include +#include #include #include #include #include #include #include namespace mitk { ItkImageIO::ItkImageIO(const ItkImageIO& other) : AbstractFileIO(other) , m_ImageIO(dynamic_cast(other.m_ImageIO->Clone().GetPointer())) { } 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; + MITK_DEBUG << "Fixing up known extensions for " << imageIOName; } return extensions; } ItkImageIO::ItkImageIO(itk::ImageIOBase::Pointer imageIO) : AbstractFileIO(Image::GetStaticNameOfClass()) , m_ImageIO(imageIO) { if (m_ImageIO.IsNull() ) { mitkThrow() << "ITK ImageIOBase argument must not be NULL"; } + this->AbstractFileReader::SetMimeTypePrefix(IOMimeTypes::DEFAULT_BASE_NAME() + ".image."); + std::vector readExtensions = m_ImageIO->GetSupportedReadExtensions(); + if (readExtensions.empty()) { std::string imageIOName = m_ImageIO->GetNameOfClass(); - MITK_WARN << "ITK ImageIOBase " << imageIOName << " does not provide read extensions"; + MITK_DEBUG << "ITK ImageIOBase " << imageIOName << " does not provide read extensions"; readExtensions = FixUpImageIOExtensions(imageIOName); } CustomMimeType customReaderMimeType; customReaderMimeType.SetCategory("Images"); for(std::vector::const_iterator iter = readExtensions.begin(), endIter = readExtensions.end(); iter != endIter; ++iter) { std::string extension = *iter; if (!extension.empty() && extension[0] == '.') { extension.assign(iter->begin()+1, iter->end()); } customReaderMimeType.AddExtension(extension); } this->AbstractFileReader::SetMimeType(customReaderMimeType); std::vector writeExtensions = imageIO->GetSupportedWriteExtensions(); if (writeExtensions.empty()) { std::string imageIOName = imageIO->GetNameOfClass(); - MITK_WARN << "ITK ImageIOBase " << imageIOName << " does not provide write extensions"; + MITK_DEBUG << "ITK ImageIOBase " << imageIOName << " does not provide write extensions"; writeExtensions = FixUpImageIOExtensions(imageIOName); } - CustomMimeType customWriterMimeType; - customWriterMimeType.SetCategory("Images"); - if (writeExtensions == readExtensions) - { - customWriterMimeType.AddExtension(customReaderMimeType.GetExtensions().front()); - } - else + if (writeExtensions != readExtensions) { + CustomMimeType customWriterMimeType; + customWriterMimeType.SetCategory("Images"); for(std::vector::const_iterator iter = writeExtensions.begin(), endIter = writeExtensions.end(); iter != endIter; ++iter) { std::string extension = *iter; if (!extension.empty() && extension[0] == '.') { extension.assign(iter->begin()+1, iter->end()); } customWriterMimeType.AddExtension(extension); } + this->AbstractFileWriter::SetMimeType(customWriterMimeType); } - this->AbstractFileWriter::SetMimeType(customWriterMimeType); std::string description = std::string("ITK ") + imageIO->GetNameOfClass(); this->SetReaderDescription(description); this->SetWriterDescription(description); this->RegisterService(); } +ItkImageIO::ItkImageIO(const CustomMimeType& mimeType, itk::ImageIOBase::Pointer imageIO, int rank) + : AbstractFileIO(Image::GetStaticNameOfClass(), mimeType, std::string("ITK ") + imageIO->GetNameOfClass()) + , m_ImageIO(imageIO) +{ + if (m_ImageIO.IsNull() ) + { + mitkThrow() << "ITK ImageIOBase argument must not be NULL"; + } + + this->AbstractFileReader::SetMimeTypePrefix(IOMimeTypes::DEFAULT_BASE_NAME() + ".image."); + + if (rank) + { + this->AbstractFileReader::SetRanking(rank); + this->AbstractFileWriter::SetRanking(rank); + } + + this->RegisterService(); +} + std::vector ItkImageIO::Read() { 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; } } Image::Pointer image = Image::New(); const unsigned int MINDIM = 2; const unsigned int MAXDIM = 4; const std::string path = this->GetLocalFileName(); 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::ItkImageIO "; } // Got to allocate space for the image. Determine the characteristics of // the image. m_ImageIO->SetFileName( path ); m_ImageIO->ReadImageInformation(); unsigned int ndim = m_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 ] = m_ImageIO->GetDimensions( i ); if(iGetDimensions( i ); spacing[ i ] = m_ImageIO->GetSpacing( i ); if(spacing[ i ] <= 0) spacing[ i ] = 1.0f; } if(i<3) { origin[ i ] = m_ImageIO->GetOrigin( i ); } } ioRegion.SetSize( ioSize ); ioRegion.SetIndex( ioStart ); MITK_INFO << "ioRegion: " << ioRegion << std::endl; m_ImageIO->SetIORegion( ioRegion ); void* buffer = new unsigned char[m_ImageIO->GetImageSizeInBytes()]; m_ImageIO->Read( buffer ); image->Initialize( MakePixelType(m_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] = m_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 = m_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; } AbstractFileIO::ConfidenceLevel ItkImageIO::GetReaderConfidenceLevel() const { return m_ImageIO->CanReadFile(GetLocalFileName().c_str()) ? IFileReader::Supported : IFileReader::Unsupported; } void ItkImageIO::Write() { const mitk::Image* image = dynamic_cast(this->GetInput()); if (image == NULL) { mitkThrow() << "Cannot write non-image data"; } struct LocaleSwitch { LocaleSwitch(const std::string& newLocale) : m_OldLocale(std::setlocale(LC_ALL, NULL)) , m_NewLocale(newLocale) { if (m_OldLocale == NULL) { m_OldLocale = ""; } else if (m_NewLocale != m_OldLocale) { // set the locale if (std::setlocale(LC_ALL, m_NewLocale.c_str()) == NULL) { MITK_INFO << "Could not set locale " << m_NewLocale; m_OldLocale = NULL; } } } ~LocaleSwitch() { if (m_OldLocale != NULL && std::setlocale(LC_ALL, m_OldLocale) == NULL) { MITK_INFO << "Could not reset locale " << m_OldLocale; } } private: const char* m_OldLocale; const std::string m_NewLocale; }; // Switch the current locale to "C" LocaleSwitch localeSwitch("C"); // Clone the image geometry, because we might have to change it // for writing purposes BaseGeometry::Pointer geometry = image->GetGeometry()->Clone(); // Check if geometry information will be lost if (image->GetDimension() == 2 && !geometry->Is2DConvertable()) { MITK_WARN << "Saving a 2D image with 3D geometry information. Geometry information will be lost! You might consider using Convert2Dto3DImageFilter before saving."; // set matrix to identity mitk::AffineTransform3D::Pointer affTrans = mitk::AffineTransform3D::New(); affTrans->SetIdentity(); mitk::Vector3D spacing = geometry->GetSpacing(); mitk::Point3D origin = geometry->GetOrigin(); geometry->SetIndexToWorldTransform(affTrans); geometry->SetSpacing(spacing); geometry->SetOrigin(origin); } LocalFile localFile(this); const std::string path = localFile.GetFileName(); MITK_INFO << "Writing image: " << path << std::endl; try { // Implementation of writer using itkImageIO directly. This skips the use // of templated itkImageFileWriter, which saves the multiplexing on MITK side. const unsigned int dimension = image->GetDimension(); const unsigned int* const dimensions = image->GetDimensions(); const mitk::PixelType pixelType = image->GetPixelType(); const mitk::Vector3D mitkSpacing = geometry->GetSpacing(); const mitk::Point3D mitkOrigin = geometry->GetOrigin(); // Due to templating in itk, we are forced to save a 4D spacing and 4D Origin, // though they are not supported in MITK itk::Vector spacing4D; spacing4D[0] = mitkSpacing[0]; spacing4D[1] = mitkSpacing[1]; spacing4D[2] = mitkSpacing[2]; spacing4D[3] = 1; // There is no support for a 4D spacing. However, we should have a valid value here itk::Vector origin4D; origin4D[0] = mitkOrigin[0]; origin4D[1] = mitkOrigin[1]; origin4D[2] = mitkOrigin[2]; origin4D[3] = 0; // There is no support for a 4D origin. However, we should have a valid value here // Set the necessary information for imageIO m_ImageIO->SetNumberOfDimensions(dimension); m_ImageIO->SetPixelType(pixelType.GetPixelType()); m_ImageIO->SetComponentType(pixelType.GetComponentType() < PixelComponentUserType ? static_cast(pixelType.GetComponentType()) : itk::ImageIOBase::UNKNOWNCOMPONENTTYPE); m_ImageIO->SetNumberOfComponents( pixelType.GetNumberOfComponents() ); itk::ImageIORegion ioRegion( dimension ); for(unsigned int i = 0; i < dimension; i++) { m_ImageIO->SetDimensions(i, dimensions[i]); m_ImageIO->SetSpacing(i, spacing4D[i]); m_ImageIO->SetOrigin(i, origin4D[i]); mitk::Vector3D mitkDirection; mitkDirection.SetVnlVector(geometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i)); itk::Vector direction4D; direction4D[0] = mitkDirection[0]; direction4D[1] = mitkDirection[1]; direction4D[2] = mitkDirection[2]; // MITK only supports a 3x3 direction matrix. Due to templating in itk, however, we must // save a 4x4 matrix for 4D images. in this case, add an homogneous component to the matrix. if (i == 3) { direction4D[3] = 1; // homogenous component } else { direction4D[3] = 0; } vnl_vector axisDirection(dimension); for(unsigned int j = 0; j < dimension; j++) { axisDirection[j] = direction4D[j] / spacing4D[i]; } m_ImageIO->SetDirection(i, axisDirection); ioRegion.SetSize(i, image->GetLargestPossibleRegion().GetSize(i)); ioRegion.SetIndex(i, image->GetLargestPossibleRegion().GetIndex(i)); } //use compression if available m_ImageIO->UseCompressionOn(); m_ImageIO->SetIORegion(ioRegion); m_ImageIO->SetFileName(path); // ***** Remove const_cast after bug 17952 is fixed **** ImageReadAccessor imageAccess(const_cast(image)); m_ImageIO->Write(imageAccess.GetData()); } catch (const std::exception& e) { mitkThrow() << e.what(); } } AbstractFileIO::ConfidenceLevel ItkImageIO::GetWriterConfidenceLevel() const { // Check if the image dimension is supported const Image* image = dynamic_cast(this->GetInput()); if (image == NULL || !m_ImageIO->SupportsDimension(image->GetDimension())) { return IFileWriter::Unsupported; } // Check if geometry information will be lost if (image->GetDimension() == 2 && !image->GetGeometry()->Is2DConvertable()) { return IFileWriter::PartiallySupported; } return IFileWriter::Supported; } ItkImageIO* ItkImageIO::IOClone() const { return new ItkImageIO(*this); } } diff --git a/Core/Code/Internal/mitkItkImageIO.h b/Core/Code/Internal/mitkItkImageIO.h index db0bd4aeb3..ef49973990 100644 --- a/Core/Code/Internal/mitkItkImageIO.h +++ b/Core/Code/Internal/mitkItkImageIO.h @@ -1,61 +1,62 @@ /*=================================================================== 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 MITKITKFILEIO_H #define MITKITKFILEIO_H #include "mitkAbstractFileIO.h" #include namespace mitk { // This class wraps ITK image IO objects registered via the // ITK object factory system class ItkImageIO : public AbstractFileIO { public: ItkImageIO(itk::ImageIOBase::Pointer imageIO); + ItkImageIO(const CustomMimeType& mimeType, itk::ImageIOBase::Pointer imageIO, int rank); // -------------- AbstractFileReader ------------- using AbstractFileReader::Read; virtual std::vector > Read(); virtual ConfidenceLevel GetReaderConfidenceLevel() const; // -------------- AbstractFileWriter ------------- virtual void Write(); virtual ConfidenceLevel GetWriterConfidenceLevel() const; private: ItkImageIO(const ItkImageIO& other); ItkImageIO* IOClone() const; std::vector FixUpImageIOExtensions(const std::string& imageIOName); itk::ImageIOBase::Pointer m_ImageIO; }; } // namespace mitk #endif /* MITKITKFILEIO_H */ diff --git a/Core/Code/Internal/mitkLegacyFileReaderService.cpp b/Core/Code/Internal/mitkLegacyFileReaderService.cpp index 4077c4c71d..870114d0cb 100644 --- a/Core/Code/Internal/mitkLegacyFileReaderService.cpp +++ b/Core/Code/Internal/mitkLegacyFileReaderService.cpp @@ -1,125 +1,126 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkLegacyFileReaderService.h" #include #include #include +#include #include mitk::LegacyFileReaderService::LegacyFileReaderService(const mitk::LegacyFileReaderService& other) : mitk::AbstractFileReader(other) { } mitk::LegacyFileReaderService::LegacyFileReaderService(const std::vector& extensions, const std::string& category) : AbstractFileReader() { - this->SetMimeTypePrefix("application/vnd.mitk.legacy."); + this->SetMimeTypePrefix(IOMimeTypes::DEFAULT_BASE_NAME() + ".legacy."); CustomMimeType customMimeType; customMimeType.SetCategory(category); for(std::vector::const_iterator iter = extensions.begin(), endIter = extensions.end(); iter != endIter; ++iter) { std::string extension = *iter; if (!extension.empty() && extension[0] == '.') { extension.assign(extension.begin()+1, extension.end()); } customMimeType.AddExtension(extension); } this->SetDescription(category); this->SetMimeType(customMimeType); m_ServiceReg = this->RegisterService(); } mitk::LegacyFileReaderService::~LegacyFileReaderService() { } ////////////////////// Reading ///////////////////////// std::vector > mitk::LegacyFileReaderService::Read() { std::vector result; std::list possibleIOAdapter; std::list allobjects = itk::ObjectFactoryBase::CreateAllInstance("mitkIOAdapter"); for( std::list::iterator i = allobjects.begin(); i != allobjects.end(); ++i) { IOAdapterBase* io = dynamic_cast(i->GetPointer()); if(io) { possibleIOAdapter.push_back(io); } else { MITK_ERROR << "Error BaseDataIO factory did not return an IOAdapterBase: " << (*i)->GetNameOfClass() << std::endl; } } const std::string path = this->GetLocalFileName(); for( std::list::iterator k = possibleIOAdapter.begin(); k != possibleIOAdapter.end(); ++k ) { bool canReadFile = (*k)->CanReadFile(path, "", ""); // they could read the file if( canReadFile ) { BaseProcess::Pointer ioObject = (*k)->CreateIOProcessObject(path, "", ""); ioObject->Update(); int numberOfContents = static_cast(ioObject->GetNumberOfOutputs()); if (numberOfContents > 0) { BaseData::Pointer baseData; for(int i=0; i(ioObject->GetOutputs()[i].GetPointer()); if (baseData) // this is what's wanted, right? { result.push_back( baseData ); } } } break; } } if (result.empty()) { mitkThrow() << "Could not read file '" << path << "'"; } return result; } mitk::LegacyFileReaderService* mitk::LegacyFileReaderService::Clone() const { return new LegacyFileReaderService(*this); } diff --git a/Core/Code/Internal/mitkLegacyFileWriterService.cpp b/Core/Code/Internal/mitkLegacyFileWriterService.cpp index 099b429ed9..83cbaf977a 100644 --- a/Core/Code/Internal/mitkLegacyFileWriterService.cpp +++ b/Core/Code/Internal/mitkLegacyFileWriterService.cpp @@ -1,85 +1,88 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkLegacyFileWriterService.h" #include +#include #include mitk::LegacyFileWriterService::LegacyFileWriterService(mitk::FileWriter::Pointer legacyWriter, const std::string& description) : AbstractFileWriter(legacyWriter->GetSupportedBaseData()) , m_LegacyWriter(legacyWriter) { - this->SetMimeTypePrefix("application/vnd.mitk.legacy."); + this->SetMimeTypePrefix(IOMimeTypes::DEFAULT_BASE_NAME() + ".legacy."); this->SetDescription(description); CustomMimeType customMimeType; std::vector extensions = legacyWriter->GetPossibleFileExtensions(); for(std::vector::iterator ext = extensions.begin(); ext != extensions.end(); ext++) { if (ext->empty()) continue; std::string extension = *ext; if (extension.size() > 1 && extension[0] == '*') { // remove "*" extension = extension.substr(1); } if (extension.size() > 1 && extension[0] == '.') { // remove "." extension = extension.substr(1); } std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); customMimeType.AddExtension(extension); } this->SetMimeType(customMimeType); m_ServiceRegistration = RegisterService(); } mitk::LegacyFileWriterService::~LegacyFileWriterService() { } ////////////////////// Writing ///////////////////////// void mitk::LegacyFileWriterService::Write() { if (m_LegacyWriter.IsNull()) mitkThrow() << "LegacyFileWriterService was incorrectly initialized: Has no LegacyFileWriter."; + ValidateOutputLocation(); + LocalFile localFile(this); m_LegacyWriter->SetFileName(localFile.GetFileName().c_str()); m_LegacyWriter->SetInput(const_cast(this->GetInput())); m_LegacyWriter->Write(); } mitk::IFileWriter::ConfidenceLevel mitk::LegacyFileWriterService::GetConfidenceLevel() const { if (mitk::AbstractFileWriter::GetConfidenceLevel() == Unsupported) return Unsupported; DataNode::Pointer node = DataNode::New(); node->SetData(const_cast(this->GetInput())); return m_LegacyWriter->CanWriteDataType(node) ? Supported : Unsupported; } mitk::LegacyFileWriterService* mitk::LegacyFileWriterService::Clone() const { return new LegacyFileWriterService(*this); } diff --git a/Core/Code/Internal/mitkPointSetReaderService.cpp b/Core/Code/Internal/mitkPointSetReaderService.cpp index 05096ee086..287b077282 100644 --- a/Core/Code/Internal/mitkPointSetReaderService.cpp +++ b/Core/Code/Internal/mitkPointSetReaderService.cpp @@ -1,129 +1,129 @@ /*=================================================================== 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. ===================================================================*/ // MITK #include "mitkPointSetReaderService.h" -#include "mitkCustomMimeType.h" +#include "mitkIOMimeTypes.h" // STL #include #include #include #include mitk::PointSetReaderService::PointSetReaderService() - : AbstractFileReader(CustomMimeType("application/vnd.mitk.pointset"), "MITK Point Set Reader") + : AbstractFileReader(CustomMimeType(IOMimeTypes::POINTSET_MIMETYPE_NAME()), "MITK Point Set Reader") { RegisterService(); } mitk::PointSetReaderService::~PointSetReaderService() {} std::vector< itk::SmartPointer > mitk::PointSetReaderService::Read() { std::locale::global(std::locale("C")); std::vector< itk::SmartPointer > result; InputStream stream(this); TiXmlDocument doc; stream >> doc; if (!doc.Error()) { TiXmlHandle docHandle( &doc ); //unsigned int pointSetCounter(0); for( TiXmlElement* currentPointSetElement = docHandle.FirstChildElement("point_set_file").FirstChildElement("point_set").ToElement(); currentPointSetElement != NULL; currentPointSetElement = currentPointSetElement->NextSiblingElement()) { mitk::PointSet::Pointer newPointSet = mitk::PointSet::New(); if(currentPointSetElement->FirstChildElement("time_series") != NULL) { for( TiXmlElement* currentTimeSeries = currentPointSetElement->FirstChildElement("time_series")->ToElement(); currentTimeSeries != NULL; currentTimeSeries = currentTimeSeries->NextSiblingElement()) { unsigned int currentTimeStep(0); TiXmlElement* currentTimeSeriesID = currentTimeSeries->FirstChildElement("time_series_id"); currentTimeStep = atoi(currentTimeSeriesID->GetText()); newPointSet = this->ReadPoint(newPointSet, currentTimeSeries, currentTimeStep); } } else { newPointSet = this->ReadPoint(newPointSet, currentPointSetElement, 0); } result.push_back( newPointSet.GetPointer() ); } } else { mitkThrow() << "Parsing error at line " << doc.ErrorRow() << ", col " << doc.ErrorCol() << ": " << doc.ErrorDesc(); } return result; } mitk::PointSet::Pointer mitk::PointSetReaderService::ReadPoint(mitk::PointSet::Pointer newPointSet, TiXmlElement* currentTimeSeries, unsigned int currentTimeStep) { if(currentTimeSeries->FirstChildElement("point") != NULL) { for( TiXmlElement* currentPoint = currentTimeSeries->FirstChildElement("point")->ToElement(); currentPoint != NULL; currentPoint = currentPoint->NextSiblingElement()) { unsigned int id(0); mitk::PointSpecificationType spec((mitk::PointSpecificationType) 0); double x(0.0); double y(0.0); double z(0.0); id = atoi(currentPoint->FirstChildElement("id")->GetText()); if(currentPoint->FirstChildElement("specification") != NULL) { spec = (mitk::PointSpecificationType) atoi(currentPoint->FirstChildElement("specification")->GetText()); } x = atof(currentPoint->FirstChildElement("x")->GetText()); y = atof(currentPoint->FirstChildElement("y")->GetText()); z = atof(currentPoint->FirstChildElement("z")->GetText()); mitk::Point3D point; mitk::FillVector3D(point, x, y, z); newPointSet->SetPoint(id, point, spec, currentTimeStep); } } else { if(currentTimeStep != newPointSet->GetTimeSteps()+1) { newPointSet->Expand(currentTimeStep+1); // expand time step series with empty time step } } return newPointSet; } mitk::PointSetReaderService::PointSetReaderService(const mitk::PointSetReaderService& other) : mitk::AbstractFileReader(other) { } mitk::PointSetReaderService* mitk::PointSetReaderService::Clone() const { return new mitk::PointSetReaderService(*this); } diff --git a/Core/Code/Internal/mitkPointSetWriterService.cpp b/Core/Code/Internal/mitkPointSetWriterService.cpp index 1188cc938f..acf8e2f955 100644 --- a/Core/Code/Internal/mitkPointSetWriterService.cpp +++ b/Core/Code/Internal/mitkPointSetWriterService.cpp @@ -1,192 +1,194 @@ /*=================================================================== 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 "mitkPointSetWriterService.h" -#include "mitkCustomMimeType.h" +#include "mitkIOMimeTypes.h" #include #include #include // // Initialization of the xml tags. // const std::string mitk::PointSetWriterService::XML_POINT_SET_FILE = "point_set_file" ; const std::string mitk::PointSetWriterService::XML_FILE_VERSION = "file_version" ; const std::string mitk::PointSetWriterService::XML_POINT_SET = "point_set" ; const std::string mitk::PointSetWriterService::XML_TIME_SERIES = "time_series"; const std::string mitk::PointSetWriterService::XML_TIME_SERIES_ID = "time_series_id"; const std::string mitk::PointSetWriterService::XML_POINT = "point" ; const std::string mitk::PointSetWriterService::XML_ID = "id" ; const std::string mitk::PointSetWriterService::XML_SPEC = "specification" ; const std::string mitk::PointSetWriterService::XML_X = "x" ; const std::string mitk::PointSetWriterService::XML_Y = "y" ; const std::string mitk::PointSetWriterService::XML_Z = "z" ; const std::string mitk::PointSetWriterService::VERSION_STRING = "0.1" ; mitk::PointSetWriterService::PointSetWriterService() - : AbstractFileWriter(PointSet::GetStaticNameOfClass(), CustomMimeType("application/vnd.mitk.pointset"), "MITK Point Set Writer") + : AbstractFileWriter(PointSet::GetStaticNameOfClass(), + CustomMimeType(IOMimeTypes::POINTSET_MIMETYPE_NAME()), + "MITK Point Set Writer") , m_IndentDepth(0) , m_Indent(2) { RegisterService(); } mitk::PointSetWriterService::PointSetWriterService(const mitk::PointSetWriterService& other) : AbstractFileWriter(other) , m_IndentDepth(other.m_IndentDepth) , m_Indent(other.m_Indent) { } mitk::PointSetWriterService::~PointSetWriterService() {} void mitk::PointSetWriterService::Write() { OutputStream out(this); if ( !out.good() ) { mitkThrow() << "Stream not good."; } std::locale previousLocale(out.getloc()); std::locale I("C"); out.imbue(I); // // Here the actual xml writing begins // WriteXMLHeader( out ); WriteStartElement( XML_POINT_SET_FILE, out ); WriteStartElement( XML_FILE_VERSION, out ); out << VERSION_STRING; WriteEndElement( XML_FILE_VERSION, out, false ); WriteXML( static_cast(this->GetInput()), out ); WriteEndElement( XML_POINT_SET_FILE, out ); out.imbue(previousLocale); if ( !out.good() ) // some error during output { mitkThrow() << "Some error during point set writing."; } } mitk::PointSetWriterService*mitk::PointSetWriterService::Clone() const { return new PointSetWriterService(*this); } void mitk::PointSetWriterService::WriteXML( const mitk::PointSet* pointSet, std::ostream& out ) { WriteStartElement( XML_POINT_SET, out ); unsigned int timecount = pointSet->GetTimeSteps(); for(unsigned int i=0; i< timecount; i++) { WriteStartElement( XML_TIME_SERIES, out ); WriteStartElement( XML_TIME_SERIES_ID, out ); out << ConvertToString( i ); WriteEndElement( XML_TIME_SERIES_ID, out, false ); mitk::PointSet::PointsContainer* pointsContainer = pointSet->GetPointSet(i)->GetPoints(); mitk::PointSet::PointsContainer::Iterator it; for ( it = pointsContainer->Begin(); it != pointsContainer->End(); ++it ) { WriteStartElement( XML_POINT, out ); WriteStartElement( XML_ID, out ); out << ConvertToString( it->Index() ); WriteEndElement( XML_ID, out, false ); mitk::PointSet::PointType point = it->Value(); WriteStartElement( XML_SPEC, out ); out << ConvertToString( pointSet->GetSpecificationTypeInfo(it->Index(), i) ); WriteEndElement( XML_SPEC, out, false ); WriteStartElement( XML_X, out ); out << ConvertToString( point[ 0 ] ); WriteEndElement( XML_X, out, false ); WriteStartElement( XML_Y, out ); out << ConvertToString( point[ 1 ] ); WriteEndElement( XML_Y, out, false ); WriteStartElement( XML_Z, out ); out << ConvertToString( point[ 2 ] ); WriteEndElement( XML_Z, out, false ); WriteEndElement( XML_POINT, out ); } WriteEndElement( XML_TIME_SERIES, out ); } WriteEndElement( XML_POINT_SET, out ); } template < typename T> std::string mitk::PointSetWriterService::ConvertToString( T value ) { std::ostringstream o; std::locale I("C"); o.imbue(I); if ( o << value ) { return o.str(); } else { return "conversion error"; } } void mitk::PointSetWriterService::WriteXMLHeader( std::ostream &file ) { file << ""; } void mitk::PointSetWriterService::WriteStartElement( const std::string& tag, std::ostream &file ) { file << std::endl; WriteIndent( file ); file << '<' << tag << '>'; m_IndentDepth++; } void mitk::PointSetWriterService::WriteEndElement( const std::string& tag, std::ostream &file, const bool& indent ) { m_IndentDepth--; if ( indent ) { file << std::endl; WriteIndent( file ); } file << '<' << '/' << tag << '>'; } void mitk::PointSetWriterService::WriteIndent( std::ostream& file ) { std::string spaces( m_IndentDepth * m_Indent, ' ' ); file << spaces; } diff --git a/Core/Code/Internal/mitkRawImageFileReader.cpp b/Core/Code/Internal/mitkRawImageFileReader.cpp index cc2929554b..7b260874f3 100644 --- a/Core/Code/Internal/mitkRawImageFileReader.cpp +++ b/Core/Code/Internal/mitkRawImageFileReader.cpp @@ -1,181 +1,182 @@ /*=================================================================== 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 "mitkRawImageFileReader.h" #include "mitkITKImageImport.h" #include "mitkImageCast.h" #include "mitkIOConstants.h" +#include "mitkIOMimeTypes.h" #include #include #include mitk::RawImageFileReader::RawImageFileReader() - : AbstractFileReader("raw", "ITK raw image reader") + : AbstractFileReader(CustomMimeType(IOMimeTypes::RAW_MIMETYPE_NAME()), "ITK raw image reader") { Options defaultOptions; defaultOptions[IOConstants::PIXEL_TYPE()] = IOConstants::PIXEL_TYPE_USHORT(); std::vector pixelEnum; pixelEnum.push_back(IOConstants::PIXEL_TYPE_UCHAR()); pixelEnum.push_back(IOConstants::PIXEL_TYPE_CHAR()); pixelEnum.push_back(IOConstants::PIXEL_TYPE_USHORT()); pixelEnum.push_back(IOConstants::PIXEL_TYPE_SHORT()); pixelEnum.push_back(IOConstants::PIXEL_TYPE_UINT()); pixelEnum.push_back(IOConstants::PIXEL_TYPE_INT()); pixelEnum.push_back(IOConstants::PIXEL_TYPE_FLOAT()); pixelEnum.push_back(IOConstants::PIXEL_TYPE_DOUBLE()); defaultOptions[IOConstants::PIXEL_TYPE_ENUM()] = pixelEnum; defaultOptions[IOConstants::DIMENSION()] = std::string("3"); std::vector dimEnum; dimEnum.push_back("2"); dimEnum.push_back("3"); defaultOptions[IOConstants::DIMENSION_ENUM()] = dimEnum; defaultOptions[IOConstants::ENDIANNESS()] = IOConstants::ENDIANNESS_LITTLE(); std::vector endianEnum; endianEnum.push_back(IOConstants::ENDIANNESS_LITTLE()); endianEnum.push_back(IOConstants::ENDIANNESS_BIG()); defaultOptions[IOConstants::ENDIANNESS_ENUM()] = endianEnum; defaultOptions[IOConstants::SIZE_X()] = 0; defaultOptions[IOConstants::SIZE_Y()] = 0; defaultOptions[IOConstants::SIZE_Z()] = 0; //defaultOptions[IOConstants::SIZE_T()] = 0; this->SetDefaultOptions(defaultOptions); this->RegisterService(); } mitk::RawImageFileReader::RawImageFileReader(const mitk::RawImageFileReader& other) : AbstractFileReader(other) { } std::vector > mitk::RawImageFileReader::Read() { std::vector result; const std::string path = this->GetLocalFileName(); const Options options = this->GetOptions(); const std::string dimensionality = options.find(IOConstants::DIMENSION())->second.ToString(); const std::string pixelType = options.find(IOConstants::PIXEL_TYPE())->second.ToString(); EndianityType endianity = options.find(IOConstants::ENDIANNESS())->second.ToString() == IOConstants::ENDIANNESS_LITTLE() ? LITTLE : BIG; int dimensions[4]; dimensions[0] = us::any_cast(options.find(IOConstants::SIZE_X())->second); dimensions[1] = us::any_cast(options.find(IOConstants::SIZE_Y())->second); dimensions[2] = us::any_cast(options.find(IOConstants::SIZE_Z())->second); dimensions[3] = 0 ;//us::any_cast(options.find(IOConstants::SIZE_T())->second); // check file dimensionality and pixel type and perform reading according to it if (dimensionality == "2") { if (pixelType == IOConstants::PIXEL_TYPE_CHAR()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_UCHAR()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_SHORT()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_USHORT()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_UINT()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_INT()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_FLOAT()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_DOUBLE())result.push_back(TypedRead(path, endianity, dimensions)); else { MITK_INFO << "Error while reading raw file: Dimensionality or pixel type not supported or not properly set" << std::endl; } } else if (dimensionality == "3") { if (pixelType == IOConstants::PIXEL_TYPE_CHAR()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_UCHAR()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_SHORT()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_USHORT()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_UINT()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_INT()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_FLOAT()) result.push_back(TypedRead(path, endianity, dimensions)); else if (pixelType == IOConstants::PIXEL_TYPE_DOUBLE()) result.push_back(TypedRead(path, endianity, dimensions)); else { MITK_INFO << "Error while reading raw file: Dimensionality or pixel type not supported or not properly set" << std::endl; } } else { MITK_INFO << "Error while reading raw file: Dimensionality not supported" << std::endl; } return result; } template < typename TPixel, unsigned int VImageDimensions > mitk::BaseData::Pointer mitk::RawImageFileReader::TypedRead(const std::string& path, EndianityType endianity, int* size) { typedef itk::Image< TPixel, VImageDimensions > ImageType; typedef itk::ImageFileReader< ImageType > ReaderType; typedef itk::RawImageIO< TPixel, VImageDimensions > IOType; typename ReaderType::Pointer reader = ReaderType::New(); typename IOType::Pointer io = IOType::New(); io->SetFileDimensionality(VImageDimensions); for (unsigned short int dim = 0; dim < VImageDimensions; ++dim) { io->SetDimensions(dim, size[dim] ); } if (endianity == LITTLE) { io->SetByteOrderToLittleEndian(); } else if (endianity == BIG) { io->SetByteOrderToBigEndian(); } else { MITK_INFO << "Warning: endianity not properly set. Resulting image might be incorrect"; } reader->SetImageIO( io ); reader->SetFileName(path); try { reader->Update(); } catch( itk::ExceptionObject & err ) { MITK_ERROR <<"An error occurred during the raw image reading process: "; MITK_INFO << err << std::endl; } mitk::Image::Pointer image = mitk::Image::New(); mitk::CastToMitkImage(reader->GetOutput(), image); image->SetVolume( reader->GetOutput()->GetBufferPointer()); return image.GetPointer(); } mitk::RawImageFileReader*mitk::RawImageFileReader::Clone() const { return new RawImageFileReader(*this); } diff --git a/Core/Code/Internal/mitkSurfaceStlIO.cpp b/Core/Code/Internal/mitkSurfaceStlIO.cpp new file mode 100644 index 0000000000..1d0c3d7319 --- /dev/null +++ b/Core/Code/Internal/mitkSurfaceStlIO.cpp @@ -0,0 +1,161 @@ +/*=================================================================== + +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 "mitkSurfaceStlIO.h" + +#include "mitkSurface.h" +#include "mitkIOMimeTypes.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace mitk { + +std::string SurfaceStlIO::OPTION_MERGE_POINTS() +{ + static std::string s = "Merge points"; + return s; +} + +std::string SurfaceStlIO::OPTION_TAG_SOLIDS() +{ + static std::string s = "Tag solids"; + return s; +} + +std::string SurfaceStlIO::OPTION_CLEAN() +{ + static std::string s = "Clean poly data"; + return s; +} + +SurfaceStlIO::SurfaceStlIO() + : SurfaceVtkIO(Surface::GetStaticNameOfClass(), IOMimeTypes::STEREOLITHOGRAPHY_MIMETYPE(), "Stereolithography") +{ + Options defaultOptions; + + defaultOptions[OPTION_MERGE_POINTS()] = us::Any(true); + defaultOptions[OPTION_TAG_SOLIDS()] = us::Any(false); + defaultOptions[OPTION_CLEAN()] = us::Any(true); + + this->SetDefaultReaderOptions(defaultOptions); + + this->RegisterService(); +} + +std::vector > SurfaceStlIO::Read() +{ + Options options = this->GetReaderOptions(); + + mitk::Surface::Pointer output = mitk::Surface::New(); + + vtkSmartPointer stlReader = vtkSmartPointer::New(); + stlReader->SetFileName(this->GetLocalFileName().c_str()); + + bool mergePoints = true; + bool tagSolids = false; + bool cleanData = true; + + try + { + mergePoints = us::any_cast(options[OPTION_MERGE_POINTS()]); + tagSolids = us::any_cast(options[OPTION_TAG_SOLIDS()]); + cleanData = us::any_cast(options[OPTION_CLEAN()]); + } + catch (const us::BadAnyCastException& e) + { + MITK_WARN << "Unexpected error: " << e.what(); + } + + stlReader->SetMerging(mergePoints); + stlReader->SetScalarTags(tagSolids); + + vtkSmartPointer normalsGenerator = vtkSmartPointer::New(); + normalsGenerator->SetInputConnection(stlReader->GetOutputPort()); + + vtkSmartPointer algo = normalsGenerator; + if (cleanData) + { + vtkSmartPointer cleanPolyDataFilter = vtkSmartPointer::New(); + cleanPolyDataFilter->SetInputConnection(normalsGenerator->GetOutputPort()); + cleanPolyDataFilter->PieceInvariantOff(); + cleanPolyDataFilter->ConvertLinesToPointsOff(); + cleanPolyDataFilter->ConvertPolysToLinesOff(); + cleanPolyDataFilter->ConvertStripsToPolysOff(); + if (mergePoints) + { + cleanPolyDataFilter->PointMergingOn(); + } + algo = cleanPolyDataFilter; + } + algo->Update(); + + if (algo->GetOutput() != NULL) + { + vtkSmartPointer surfaceWithNormals = algo->GetOutput(); + output->SetVtkPolyData(surfaceWithNormals); + } + + std::vector result; + result.push_back(output.GetPointer()); + return result; +} + +void SurfaceStlIO::Write() +{ + ValidateOutputLocation(); + + const Surface* input = dynamic_cast(this->GetInput()); + + const unsigned int timesteps = input->GetTimeGeometry()->CountTimeSteps(); + for(unsigned int t = 0; t < timesteps; ++t) + { + std::string fileName; + vtkSmartPointer polyData = this->GetPolyData(t, fileName); + vtkSmartPointer triangleFilter = vtkSmartPointer::New(); + triangleFilter->SetInputData(polyData); + vtkSmartPointer writer = vtkSmartPointer::New(); + writer->SetInputConnection(triangleFilter->GetOutputPort()); + + // The vtk stl writer cannot write to streams + LocalFile localFile(this); + writer->SetFileName(localFile.GetFileName().c_str()); + + if (writer->Write() == 0 || writer->GetErrorCode() != 0 ) + { + mitkThrow() << "Error during surface writing: " << vtkErrorCode::GetStringFromErrorCode(writer->GetErrorCode()); + } + + if (this->GetOutputStream() && input->GetTimeGeometry()->CountTimeSteps() > 1) + { + MITK_WARN << "Writing multiple time-steps to output streams is not supported. " + << "Only the first time-step will be written"; + break; + } + } +} + +SurfaceStlIO* SurfaceStlIO::IOClone() const +{ + return new SurfaceStlIO(*this); +} + +} diff --git a/Core/Code/Internal/mitkItkImageIO.h b/Core/Code/Internal/mitkSurfaceStlIO.h similarity index 53% copy from Core/Code/Internal/mitkItkImageIO.h copy to Core/Code/Internal/mitkSurfaceStlIO.h index db0bd4aeb3..8c1638b0f3 100644 --- a/Core/Code/Internal/mitkItkImageIO.h +++ b/Core/Code/Internal/mitkSurfaceStlIO.h @@ -1,61 +1,53 @@ /*=================================================================== 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 MITKITKFILEIO_H -#define MITKITKFILEIO_H +#ifndef _MITK_SURFACE_STL_IO_H_ +#define _MITK_SURFACE_STL_IO_H_ -#include "mitkAbstractFileIO.h" +#include "mitkSurfaceVtkIO.h" -#include - -namespace mitk { - -// This class wraps ITK image IO objects registered via the -// ITK object factory system -class ItkImageIO : public AbstractFileIO +namespace mitk { +class SurfaceStlIO : public mitk::SurfaceVtkIO +{ public: - ItkImageIO(itk::ImageIOBase::Pointer imageIO); + SurfaceStlIO(); // -------------- AbstractFileReader ------------- using AbstractFileReader::Read; virtual std::vector > Read(); - virtual ConfidenceLevel GetReaderConfidenceLevel() const; - // -------------- AbstractFileWriter ------------- virtual void Write(); - virtual ConfidenceLevel GetWriterConfidenceLevel() const; private: - ItkImageIO(const ItkImageIO& other); - - ItkImageIO* IOClone() const; + SurfaceStlIO* IOClone() const; - std::vector FixUpImageIOExtensions(const std::string& imageIOName); + static std::string OPTION_MERGE_POINTS(); + static std::string OPTION_TAG_SOLIDS(); + static std::string OPTION_CLEAN(); - itk::ImageIOBase::Pointer m_ImageIO; }; -} // namespace mitk +} -#endif /* MITKITKFILEIO_H */ +#endif //_MITK_SURFACE_STL_IO_H_ diff --git a/Core/Code/Internal/mitkSurfaceVtkIO.cpp b/Core/Code/Internal/mitkSurfaceVtkIO.cpp new file mode 100644 index 0000000000..47bfeabfa5 --- /dev/null +++ b/Core/Code/Internal/mitkSurfaceVtkIO.cpp @@ -0,0 +1,99 @@ +/*=================================================================== + +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 "mitkSurfaceVtkIO.h" + +#include "mitkSurface.h" + +#include +#include +#include +#include + +#include + +namespace mitk { + + +SurfaceVtkIO::SurfaceVtkIO(const std::string& baseDataType, const CustomMimeType& mimeType, + const std::string& description) + : AbstractFileIO(baseDataType, mimeType, description) +{ +} + +vtkSmartPointer SurfaceVtkIO::GetPolyData(unsigned int t, std::string& fileName) +{ + const Surface* input = dynamic_cast(this->GetInput()); + + vtkSmartPointer transformPolyData = vtkSmartPointer::New(); + + // surfaces do not have to exist in all timesteps; therefor, only write valid surfaces + if(input->GetVtkPolyData(t) == NULL) return vtkSmartPointer(); + + std::string baseName = this->GetOutputLocation(); + std::string extension = itksys::SystemTools::GetFilenameExtension(baseName); + if (!extension.empty()) + { + baseName = baseName.substr(0, baseName.size() - extension.size()); + } + + std::ostringstream ss; + ss.imbue(::std::locale::classic()); + + BaseGeometry* geometry = input->GetGeometry(t); + if(input->GetTimeGeometry()->IsValidTimeStep(t)) + { + if (input->GetTimeGeometry()->CountTimeSteps() > 1) + { + const TimeBounds& timebounds = input->GetTimeGeometry()->GetTimeBounds(t); + ss << baseName << "_S" << std::setprecision(0) << timebounds[0] << "_E" << std::setprecision(0) << timebounds[1] << "_T" << t << extension; + } + else + { + // use the original file name + ss << this->GetOutputLocation(); + } + } + else + { + MITK_WARN << "Error on write: TimeGeometry invalid of surface " << fileName << "."; + return vtkSmartPointer(); + } + + fileName = ss.str(); + + transformPolyData->SetInputData(input->GetVtkPolyData(t)); + transformPolyData->SetTransform(geometry->GetVtkTransform()); + transformPolyData->UpdateWholeExtent(); + + vtkSmartPointer polyData = transformPolyData->GetOutput(); + return polyData; +} + +IFileIO::ConfidenceLevel SurfaceVtkIO::GetWriterConfidenceLevel() const +{ + if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported; + if (this->GetInput()->GetTimeGeometry()->CountTimeSteps() > 1) + { + // The VTK formats don't support multiple time points. + // During writing, we write each time step into a separate file. + // For output streams, we only write the first time-step and print a warning. + return PartiallySupported; + } + return Supported; +} + +} diff --git a/Core/Code/Internal/mitkSurfaceVtkIO.h b/Core/Code/Internal/mitkSurfaceVtkIO.h new file mode 100644 index 0000000000..8da649c81d --- /dev/null +++ b/Core/Code/Internal/mitkSurfaceVtkIO.h @@ -0,0 +1,59 @@ +/*=================================================================== + +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 _MITK_SURFACE_VTK_IO_H_ +#define _MITK_SURFACE_VTK_IO_H_ + +#include + +#include +#include + +namespace mitk +{ + +/** + * @brief VTK-based reader and writer for mitk::Surface + * + * If the mitk::Surface contains multiple points of + * time, multiple files are written. The life-span (time-bounds) of each + * each point of time is included in the filename according to the + * following scheme: + * <filename>_S<timebounds[0]>E<timebounds[1]>_T<framenumber> + * (S=start, E=end, T=time). + * Writing of multiple files according to a given filename pattern is not + * yet supported. + * @ingroup Process + */ +class SurfaceVtkIO : public mitk::AbstractFileIO +{ +public: + + SurfaceVtkIO(const std::string& baseDataType, const CustomMimeType& mimeType, + const std::string& description); + + virtual ConfidenceLevel GetWriterConfidenceLevel() const; + +protected: + + vtkSmartPointer GetPolyData(unsigned int t, std::string& fileName); + +}; + +} + +#endif //_MITK_SURFACE_VTK_IO_H_ diff --git a/Core/Code/Internal/mitkSurfaceVtkLegacyIO.cpp b/Core/Code/Internal/mitkSurfaceVtkLegacyIO.cpp new file mode 100644 index 0000000000..844ab19665 --- /dev/null +++ b/Core/Code/Internal/mitkSurfaceVtkLegacyIO.cpp @@ -0,0 +1,111 @@ +/*=================================================================== + +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 "mitkSurfaceVtkLegacyIO.h" + +#include "mitkSurface.h" +#include "mitkIOMimeTypes.h" + +#include +#include +#include +#include +#include +#include + +namespace mitk { + +SurfaceVtkLegacyIO::SurfaceVtkLegacyIO() + : SurfaceVtkIO(Surface::GetStaticNameOfClass(), IOMimeTypes::VTK_POLYDATA_LEGACY_MIMETYPE(), "VTK Legacy PolyData") +{ + this->RegisterService(); +} + +std::vector > SurfaceVtkLegacyIO::Read() +{ + mitk::Surface::Pointer output = mitk::Surface::New(); + + // The legay vtk reader cannot work with input streams + const std::string fileName = this->GetLocalFileName(); + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(fileName.c_str()); + reader->Update(); + + if ( reader->GetOutput() != NULL ) + { + output->SetVtkPolyData(reader->GetOutput()); + } + else + { + mitkThrow() << "vtkPolyDataReader error: " << vtkErrorCode::GetStringFromErrorCode(reader->GetErrorCode()); + } + + std::vector result; + result.push_back(output.GetPointer()); + return result; +} + +IFileIO::ConfidenceLevel SurfaceVtkLegacyIO::GetReaderConfidenceLevel() const +{ + if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(this->GetLocalFileName().c_str()); + if (reader->IsFilePolyData()) + { + return Supported; + } + return Unsupported; +} + +void SurfaceVtkLegacyIO::Write() +{ + ValidateOutputLocation(); + + const Surface* input = dynamic_cast(this->GetInput()); + + const unsigned int timesteps = input->GetTimeGeometry()->CountTimeSteps(); + for(unsigned int t = 0; t < timesteps; ++t) + { + std::string fileName; + vtkSmartPointer polyData = this->GetPolyData(t, fileName); + vtkSmartPointer writer = vtkSmartPointer::New(); + writer->SetInputData(polyData); + + // The legacy vtk poly data writer cannot write to streams + LocalFile localFile(this); + writer->SetFileName(localFile.GetFileName().c_str()); + + if (writer->Write() == 0 || writer->GetErrorCode() != 0 ) + { + mitkThrow() << "Error during surface writing: " << vtkErrorCode::GetStringFromErrorCode(writer->GetErrorCode()); + } + + if (this->GetOutputStream() && input->GetTimeGeometry()->CountTimeSteps() > 1) + { + MITK_WARN << "Writing multiple time-steps to output streams is not supported. " + << "Only the first time-step will be written"; + break; + } + } +} + + +SurfaceVtkLegacyIO* SurfaceVtkLegacyIO::IOClone() const +{ + return new SurfaceVtkLegacyIO(*this); +} + +} diff --git a/Core/Code/Internal/mitkItkImageIO.h b/Core/Code/Internal/mitkSurfaceVtkLegacyIO.h similarity index 53% copy from Core/Code/Internal/mitkItkImageIO.h copy to Core/Code/Internal/mitkSurfaceVtkLegacyIO.h index db0bd4aeb3..e2d799ece9 100644 --- a/Core/Code/Internal/mitkItkImageIO.h +++ b/Core/Code/Internal/mitkSurfaceVtkLegacyIO.h @@ -1,61 +1,53 @@ /*=================================================================== 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 MITKITKFILEIO_H -#define MITKITKFILEIO_H +#ifndef _MITK_SURFACE_VTK_LEGACY_IO_H_ +#define _MITK_SURFACE_VTK_LEGACY_IO_H_ -#include "mitkAbstractFileIO.h" +#include "mitkSurfaceVtkIO.h" -#include +#include "mitkBaseData.h" -namespace mitk { - -// This class wraps ITK image IO objects registered via the -// ITK object factory system -class ItkImageIO : public AbstractFileIO +namespace mitk { +class SurfaceVtkLegacyIO : public mitk::SurfaceVtkIO +{ public: - ItkImageIO(itk::ImageIOBase::Pointer imageIO); + SurfaceVtkLegacyIO(); // -------------- AbstractFileReader ------------- using AbstractFileReader::Read; - virtual std::vector > Read(); + virtual std::vector Read(); virtual ConfidenceLevel GetReaderConfidenceLevel() const; // -------------- AbstractFileWriter ------------- virtual void Write(); - virtual ConfidenceLevel GetWriterConfidenceLevel() const; private: - ItkImageIO(const ItkImageIO& other); - - ItkImageIO* IOClone() const; - - std::vector FixUpImageIOExtensions(const std::string& imageIOName); + SurfaceVtkLegacyIO* IOClone() const; - itk::ImageIOBase::Pointer m_ImageIO; }; -} // namespace mitk +} -#endif /* MITKITKFILEIO_H */ +#endif //_MITK_SURFACE_VTK_LEGACY_IO_H_ diff --git a/Core/Code/Internal/mitkSurfaceVtkXmlIO.cpp b/Core/Code/Internal/mitkSurfaceVtkXmlIO.cpp new file mode 100644 index 0000000000..853e28389d --- /dev/null +++ b/Core/Code/Internal/mitkSurfaceVtkXmlIO.cpp @@ -0,0 +1,144 @@ +/*=================================================================== + +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 "mitkSurfaceVtkXmlIO.h" + +#include "mitkSurface.h" +#include "mitkIOMimeTypes.h" + +#include +#include +#include +#include + +namespace mitk { + +class VtkXMLPolyDataReader : public ::vtkXMLPolyDataReader +{ +public: + static VtkXMLPolyDataReader *New() { return new VtkXMLPolyDataReader(); } + vtkTypeMacro(VtkXMLPolyDataReader,vtkXMLPolyDataReader) + + void SetStream(std::istream* is) { this->Stream = is; } + std::istream* GetStream() const { return this->Stream; } +}; + +class VtkXMLPolyDataWriter : public ::vtkXMLPolyDataWriter +{ +public: + static VtkXMLPolyDataWriter *New() { return new VtkXMLPolyDataWriter(); } + vtkTypeMacro(VtkXMLPolyDataWriter,vtkXMLPolyDataWriter) + + void SetStream(std::ostream* os) { this->Stream = os; } + std::ostream* GetStream() const { return this->Stream; } +}; + +SurfaceVtkXmlIO::SurfaceVtkXmlIO() + : SurfaceVtkIO(Surface::GetStaticNameOfClass(), IOMimeTypes::VTK_POLYDATA_MIMETYPE(), "VTK XML PolyData") +{ + this->RegisterService(); +} + +std::vector > SurfaceVtkXmlIO::Read() +{ + mitk::Surface::Pointer output = mitk::Surface::New(); + + vtkSmartPointer reader= vtkSmartPointer::New(); + if (this->GetInputStream()) + { + reader->SetStream(this->GetInputStream()); + } + else + { + reader->SetFileName(this->GetInputLocation().c_str()); + } + reader->Update(); + + if (reader->GetOutput() != NULL) + { + output->SetVtkPolyData(reader->GetOutput()); + } + else + { + mitkThrow() << "vtkXMLPolyDataReader error: " << vtkErrorCode::GetStringFromErrorCode(reader->GetErrorCode()); + } + + std::vector result; + result.push_back(output.GetPointer()); + return result; +} + +IFileIO::ConfidenceLevel SurfaceVtkXmlIO::GetReaderConfidenceLevel() const +{ + if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; + if (this->GetInputStream() == NULL) + { + // check if the xml vtk reader can handle the file + vtkSmartPointer xmlReader = vtkSmartPointer::New(); + if (xmlReader->CanReadFile(this->GetInputLocation().c_str()) != 0) + { + return Supported; + } + return Unsupported; + } + // in case of an input stream, VTK does not seem to have methods for + // validating it + return Supported; +} + +void SurfaceVtkXmlIO::Write() +{ + ValidateOutputLocation(); + + const Surface* input = dynamic_cast(this->GetInput()); + + const unsigned int timesteps = input->GetTimeGeometry()->CountTimeSteps(); + for(unsigned int t = 0; t < timesteps; ++t) + { + std::string fileName; + vtkSmartPointer polyData = this->GetPolyData(t, fileName); + vtkSmartPointer writer = vtkSmartPointer::New(); + writer->SetInputData(polyData); + + if (this->GetOutputStream()) + { + if (input->GetTimeGeometry()->CountTimeSteps() > 1) + { + MITK_WARN << "Writing multiple time-steps to output streams is not supported. " + << "Only the first time-step will be written"; + } + writer->SetStream(this->GetOutputStream()); + } + else + { + writer->SetFileName(fileName.c_str()); + } + + if (writer->Write() == 0 || writer->GetErrorCode() != 0 ) + { + mitkThrow() << "Error during surface writing: " << vtkErrorCode::GetStringFromErrorCode(writer->GetErrorCode()); + } + + if (this->GetOutputStream()) break; + } +} + +SurfaceVtkXmlIO* SurfaceVtkXmlIO::IOClone() const +{ + return new SurfaceVtkXmlIO(*this); +} + +} diff --git a/Core/Code/Internal/mitkItkImageIO.h b/Core/Code/Internal/mitkSurfaceVtkXmlIO.h similarity index 54% copy from Core/Code/Internal/mitkItkImageIO.h copy to Core/Code/Internal/mitkSurfaceVtkXmlIO.h index db0bd4aeb3..973a7d3088 100644 --- a/Core/Code/Internal/mitkItkImageIO.h +++ b/Core/Code/Internal/mitkSurfaceVtkXmlIO.h @@ -1,61 +1,51 @@ /*=================================================================== 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 MITKITKFILEIO_H -#define MITKITKFILEIO_H +#ifndef _MITK_SURFACE_VTK_XML_IO_H_ +#define _MITK_SURFACE_VTK_XML_IO_H_ -#include "mitkAbstractFileIO.h" +#include "mitkSurfaceVtkIO.h" -#include +#include "mitkBaseData.h" namespace mitk { -// This class wraps ITK image IO objects registered via the -// ITK object factory system -class ItkImageIO : public AbstractFileIO +class SurfaceVtkXmlIO : public mitk::SurfaceVtkIO { - public: - ItkImageIO(itk::ImageIOBase::Pointer imageIO); + SurfaceVtkXmlIO(); // -------------- AbstractFileReader ------------- using AbstractFileReader::Read; - virtual std::vector > Read(); + virtual std::vector Read(); virtual ConfidenceLevel GetReaderConfidenceLevel() const; // -------------- AbstractFileWriter ------------- virtual void Write(); - virtual ConfidenceLevel GetWriterConfidenceLevel() const; private: - ItkImageIO(const ItkImageIO& other); - - ItkImageIO* IOClone() const; - - std::vector FixUpImageIOExtensions(const std::string& imageIOName); - - itk::ImageIOBase::Pointer m_ImageIO; + SurfaceVtkXmlIO* IOClone() const; }; -} // namespace mitk +} -#endif /* MITKITKFILEIO_H */ +#endif //_MITK_SURFACE_VTK_XML_IO_H_ diff --git a/Core/Code/Testing/mitkIOUtilTest.cpp b/Core/Code/Testing/mitkIOUtilTest.cpp index 58862b4d24..3488a9cb48 100644 --- a/Core/Code/Testing/mitkIOUtilTest.cpp +++ b/Core/Code/Testing/mitkIOUtilTest.cpp @@ -1,202 +1,202 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTestingMacros.h" #include #include #include #include #include class mitkIOUtilTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkIOUtilTestSuite); - //MITK_TEST(TestTempMethods); - //MITK_TEST(TestLoadAndSaveImage); - //MITK_TEST(TestLoadAndSavePointSet); + MITK_TEST(TestTempMethods); + MITK_TEST(TestLoadAndSaveImage); + MITK_TEST(TestLoadAndSavePointSet); MITK_TEST(TestLoadAndSaveSurface); - //MITK_TEST(TestTempMethodsForUniqueFilenames); + MITK_TEST(TestTempMethodsForUniqueFilenames); CPPUNIT_TEST_SUITE_END(); private: std::string m_ImagePath; std::string m_SurfacePath; std::string m_PointSetPath; public: void setUp() { m_ImagePath = GetTestDataFilePath("Pic3D.nrrd"); m_SurfacePath = GetTestDataFilePath("binary.stl"); m_PointSetPath = GetTestDataFilePath("pointSet.mps"); } void TestTempMethods() { std::string tmpPath = mitk::IOUtil::GetTempPath(); CPPUNIT_ASSERT(!tmpPath.empty()); std::ofstream tmpFile; std::string tmpFilePath = mitk::IOUtil::CreateTemporaryFile(tmpFile); CPPUNIT_ASSERT(tmpFile && tmpFile.is_open()); CPPUNIT_ASSERT(tmpFilePath.size() > tmpPath.size()); CPPUNIT_ASSERT(tmpFilePath.substr(0, tmpPath.size()) == tmpPath); tmpFile.close(); CPPUNIT_ASSERT(std::remove(tmpFilePath.c_str()) == 0); std::string programPath = mitk::IOUtil::GetProgramPath(); CPPUNIT_ASSERT(!programPath.empty()); std::ofstream tmpFile2; std::string tmpFilePath2 = mitk::IOUtil::CreateTemporaryFile(tmpFile2, "my-XXXXXX", programPath); CPPUNIT_ASSERT(tmpFile2 && tmpFile2.is_open()); CPPUNIT_ASSERT(tmpFilePath2.size() > programPath.size()); CPPUNIT_ASSERT(tmpFilePath2.substr(0, programPath.size()) == programPath); tmpFile2.close(); CPPUNIT_ASSERT(std::remove(tmpFilePath2.c_str()) == 0); std::ofstream tmpFile3; std::string tmpFilePath3 = mitk::IOUtil::CreateTemporaryFile(tmpFile3, std::ios_base::binary, "my-XXXXXX.TXT", programPath); CPPUNIT_ASSERT(tmpFile3 && tmpFile3.is_open()); CPPUNIT_ASSERT(tmpFilePath3.size() > programPath.size()); CPPUNIT_ASSERT(tmpFilePath3.substr(0, programPath.size()) == programPath); CPPUNIT_ASSERT(tmpFilePath3.substr(tmpFilePath3.size() - 13, 3) == "my-"); CPPUNIT_ASSERT(tmpFilePath3.substr(tmpFilePath3.size() - 4) == ".TXT"); tmpFile3.close(); //CPPUNIT_ASSERT(std::remove(tmpFilePath3.c_str()) == 0) std::string tmpFilePath4 = mitk::IOUtil::CreateTemporaryFile(); std::ofstream file; file.open(tmpFilePath4.c_str()); CPPUNIT_ASSERT_MESSAGE("Testing if file exists after CreateTemporaryFile()",file.is_open()); CPPUNIT_ASSERT_THROW(mitk::IOUtil::CreateTemporaryFile(tmpFile2, "XX"), mitk::Exception); std::string tmpDir = mitk::IOUtil::CreateTemporaryDirectory(); CPPUNIT_ASSERT(tmpDir.size() > tmpPath.size()); CPPUNIT_ASSERT(tmpDir.substr(0, tmpPath.size()) == tmpPath); CPPUNIT_ASSERT(itksys::SystemTools::RemoveADirectory(tmpDir.c_str())); std::string tmpDir2 = mitk::IOUtil::CreateTemporaryDirectory("my-XXXXXX", programPath); CPPUNIT_ASSERT(tmpDir2.size() > programPath.size()); CPPUNIT_ASSERT(tmpDir2.substr(0, programPath.size()) == programPath); CPPUNIT_ASSERT(itksys::SystemTools::RemoveADirectory(tmpDir2.c_str())); } void TestTempMethodsForUniqueFilenames() { int numberOfFiles = 100; //create 100 empty files std::vector v100filenames; for(int i=0; i(4,4,4,1); std::string imagePath3 = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.nrrd"); tmpStream.close(); mitk::IOUtil::Save(relativImage, imagePath3); CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::LoadImage(imagePath3)); std::remove(imagePath3.c_str()); } void TestLoadAndSavePointSet() { mitk::PointSet::Pointer pointset = mitk::IOUtil::LoadPointSet(m_PointSetPath); CPPUNIT_ASSERT( pointset.IsNotNull()); std::ofstream tmpStream; std::string pointSetPath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.mps"); tmpStream.close(); std::string pointSetPathWithDefaultExtension = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.mps"); tmpStream.close(); - std::string pointSetPathWithoutDefaultExtension = mitk::IOUtil::CreateTemporaryFile(tmpStream, "XXXXXX.xXx"); + std::string pointSetPathWithoutDefaultExtension = mitk::IOUtil::CreateTemporaryFile(tmpStream); tmpStream.close(); // the cases where no exception should be thrown CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::Save(pointset, pointSetPathWithDefaultExtension)); // test if defaultextension is inserted if no extension is present CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::Save(pointset, pointSetPathWithoutDefaultExtension.c_str())); //delete the files after the test is done std::remove(pointSetPath.c_str()); std::remove(pointSetPathWithDefaultExtension.c_str()); std::remove(pointSetPathWithoutDefaultExtension.c_str()); } void TestLoadAndSaveSurface() { mitk::Surface::Pointer surface = mitk::IOUtil::LoadSurface(m_SurfacePath); CPPUNIT_ASSERT( surface.IsNotNull()); std::ofstream tmpStream; std::string surfacePath = mitk::IOUtil::CreateTemporaryFile(tmpStream, "diffsurface-XXXXXX.stl"); // the cases where no exception should be thrown CPPUNIT_ASSERT_NO_THROW(mitk::IOUtil::Save(surface, surfacePath)); // test if exception is thrown as expected on unknown extsension CPPUNIT_ASSERT_THROW(mitk::IOUtil::Save(surface,"testSurface.xXx"), mitk::Exception); //delete the files after the test is done std::remove(surfacePath.c_str()); } }; MITK_TEST_SUITE_REGISTRATION(mitkIOUtil) diff --git a/Core/Code/files.cmake b/Core/Code/files.cmake index 3bf0e93a51..ee9c44b05b 100644 --- a/Core/Code/files.cmake +++ b/Core/Code/files.cmake @@ -1,412 +1,419 @@ 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 Common/mitkGetClassHierarchy.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/mitkImageReadAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageVtkReadAccessor.cpp DataManagement/mitkImageVtkWriteAccessor.cpp DataManagement/mitkImageWriteAccessor.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLine.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/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/mitkCustomMimeType.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/mitkFileReaderRegistry.cpp IO/mitkFileReaderSelector.cpp IO/mitkFileWriter.cpp IO/mitkFileWriterRegistry.cpp IO/mitkFileWriterSelector.cpp IO/mitkIFileIO.cpp # IO/mitkIpPicGet.c IO/mitkImageGenerator.cpp IO/mitkIOConstants.cpp IO/mitkIOUtil.cpp + IO/mitkIOMimeTypes.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkMimeType.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/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 Common/mitkException.cpp Common/mitkCoreObjectFactoryBase.cpp Common/mitkCoreObjectFactory.cpp Common/mitkCoreServices.cpp Internal/mitkCoreActivator.cpp Internal/mitkFileReaderWriterBase.cpp + Internal/mitkImageVtkLegacyIO.cpp + Internal/mitkImageVtkXmlIO.cpp Internal/mitkItkImageIO.cpp Internal/mitkLegacyFileReaderService.cpp Internal/mitkLegacyFileWriterService.cpp Internal/mitkMimeTypeProvider.cpp Internal/mitkPointSetReaderService.cpp Internal/mitkPointSetWriterService.cpp Internal/mitkRawImageFileReader.cpp + Internal/mitkSurfaceStlIO.cpp + Internal/mitkSurfaceVtkIO.cpp + Internal/mitkSurfaceVtkLegacyIO.cpp + Internal/mitkSurfaceVtkXmlIO.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/Examples/Tutorial/ITKAndVTK/CMakeLists.txt b/Examples/Tutorial/ITKAndVTK/CMakeLists.txt index d76ab10025..7ae4d36f53 100644 --- a/Examples/Tutorial/ITKAndVTK/CMakeLists.txt +++ b/Examples/Tutorial/ITKAndVTK/CMakeLists.txt @@ -1,4 +1,4 @@ # adding additional example for mitk itk and vtk interaction mitk_create_executable(MitkWithITKAndVTK - DEPENDS MitkCore MitkIpPicSupport + DEPENDS MitkCore ) diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt index 30c9a2094b..0fb53ff5aa 100644 --- a/Modules/CMakeLists.txt +++ b/Modules/CMakeLists.txt @@ -1,81 +1,80 @@ # Modules must be listed according to their dependencies set(module_dirs LegacyIO DataTypesExt AlgorithmsExt MapperExt IOExt DICOMReader DICOMTesting Qt4Qt5TestModule SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction ImageStatistics LegacyAdaptors - IpPicSupport SceneSerialization GraphAlgorithms ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation OpenViewCore QmlItems Overlays QtWidgets QtWidgetsExt SegmentationUI DiffusionImaging GPGPU IGTBase IGT CameraCalibration RigidRegistration RigidRegistrationUI DeformableRegistration DeformableRegistrationUI OpenCL OpenCVVideoSupport QtOverlays InputDevices ToFHardware ToFProcessing ToFUI US USUI DicomUI Simulation Remeshing Python Persistence IGTUI VtkShaders DicomRT ) if(MITK_ENABLE_PIC_READER) list(APPEND module_dirs IpPicSupportIO) endif() set(MITK_DEFAULT_SUBPROJECTS MITK-Modules) foreach(module_dir ${module_dirs}) add_subdirectory(${module_dir}) endforeach() if(MITK_PRIVATE_MODULES) file(GLOB all_subdirs RELATIVE ${MITK_PRIVATE_MODULES} ${MITK_PRIVATE_MODULES}/*) foreach(subdir ${all_subdirs}) string(FIND ${subdir} "." _result) if(_result EQUAL -1) if(EXISTS ${MITK_PRIVATE_MODULES}/${subdir}/CMakeLists.txt) message(STATUS "Found private module ${subdir}") add_subdirectory(${MITK_PRIVATE_MODULES}/${subdir} private_modules/${subdir}) endif() endif() endforeach() endif(MITK_PRIVATE_MODULES) diff --git a/Modules/IpPicSupport/CMakeLists.txt b/Modules/IpPicSupport/CMakeLists.txt deleted file mode 100644 index 399d7f69db..0000000000 --- a/Modules/IpPicSupport/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -mitkFunctionCheckCompilerFlags("-Wno-deprecated-declarations" CMAKE_CXX_FLAGS) - -MITK_CREATE_MODULE( - DEPENDS MitkLegacyAdaptors MitkLegacyIO MitkIpPic - DEPRECATED_SINCE 2013.12 - ) - -add_subdirectory(Testing) diff --git a/Modules/IpPicSupport/Testing/CMakeLists.txt b/Modules/IpPicSupport/Testing/CMakeLists.txt deleted file mode 100644 index 46d2f08276..0000000000 --- a/Modules/IpPicSupport/Testing/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -MITK_CREATE_MODULE_TESTS(LABELS MITK-Modules) - -mitkAddCustomModuleTest(mitkPicFileReaderTest_emptyFile mitkPicFileReaderTest ${CMAKE_CURRENT_SOURCE_DIR}/Data/emptyFile.pic) -mitkAddCustomModuleTest(mitkPicFileReaderTest_emptyGzipFile mitkPicFileReaderTest ${CMAKE_CURRENT_SOURCE_DIR}/Data/emptyFile.pic.gz) - diff --git a/Modules/IpPicSupport/Testing/files.cmake b/Modules/IpPicSupport/Testing/files.cmake deleted file mode 100644 index 0083e52bfa..0000000000 --- a/Modules/IpPicSupport/Testing/files.cmake +++ /dev/null @@ -1,12 +0,0 @@ -set(MODULE_IMAGE_TESTS - #mitkPicFileIOTest.cpp - mitkPicFileWriterTest.cpp - mitkPicFileReaderTest.cpp -) - -set(MODULE_TESTIMAGES - US4DCyl.pic.gz - Pic3D.pic.gz - Pic2DplusT.pic.gz - BallBinary30x30x30.pic.gz -) diff --git a/Modules/IpPicSupport/Testing/mitkPicFileIOTest.cpp b/Modules/IpPicSupport/Testing/mitkPicFileIOTest.cpp deleted file mode 100644 index ffeb5225a2..0000000000 --- a/Modules/IpPicSupport/Testing/mitkPicFileIOTest.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/*=================================================================== - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center, -Division of Medical and Biological Informatics. -All rights reserved. - -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. - -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ - -#include "mitkImage.h" -#include "mitkPicFileReader.h" -#include "mitkImageWriter.h" -#include "mitkImageAccessByItk.h" - -#include - -unsigned int numberOfTestImages = 3; - -// create one test image -mitk::Image::Pointer CreateTestImage(unsigned int which) -{ - mitk::Image::Pointer image = mitk::Image::New(); - - switch (which) - { - case 0: - { - unsigned int dim[]={10,10,20}; // image dimensions - - image->Initialize(mitk::PixelType(typeid(int)), 3, dim); - int *p = (int*)image->GetData(); // pointer to pixel data - int size = dim[0]*dim[1]*dim[2]; - for(int i=0; iInitialize(mitk::PixelType(typeid(float)), 3, dim); - float *p = (float*)image->GetData(); // pointer to pixel data - int size = dim[0]*dim[1]*dim[2]; - for(int i=0; iInitialize(mitk::PixelType(typeid(double)), 3, dim); - double *p = (double*)image->GetData(); // pointer to pixel data - int size = dim[0]*dim[1]*dim[2]; - for(int i=0; iInitialize(mitk::PixelType(typeid(int)), 3, dim); - int *p = (int*)image->GetData(); // pointer to pixel data - int size = dim[0]*dim[1]*dim[2]; - for(int i=0; i -void ItkImageProcessing( itk::Image< TPixel, VImageDimension >* itkImage, mitk::Image* mitkImage, bool& identical ) -{ - typename itk::Image< TPixel, VImageDimension >::Pointer itkImage2; - - mitk::CastToItkImage( mitkImage, itkImage2 ); - - if (!itkImage2 || !itkImage2.GetPointer()) - { - identical = false; - return; - } - - itk::ImageRegionConstIterator > iterItkImage1( itkImage, itkImage->GetLargestPossibleRegion() ); - itk::ImageRegionConstIterator > iterItkImage2( itkImage, itkImage2->GetLargestPossibleRegion() ); - - iterItkImage1.GoToBegin(); - iterItkImage2.GoToBegin(); - - while (!iterItkImage1.IsAtEnd()) - { - if (iterItkImage1.Get() != iterItkImage2.Get()) - { - std::cout << iterItkImage1.Get() << " != " << iterItkImage2.Get() << std::endl; - identical = false; - return; - } - - ++iterItkImage1; - ++iterItkImage2; - } - - // if we reach this point, all pixel are the same - identical = true; -} - -int mitkPicFileIOTest(int, char*[]) -{ - unsigned int numberFailed(0); - - for (unsigned int i = 0; i < numberOfTestImages; ++i) - { - mitk::Image::Pointer originalImage = CreateTestImage(i); - mitk::Image::Pointer secondImage; - - // write - try - { - mitk::ImageWriter::Pointer imageWriter = mitk::ImageWriter::New(); - imageWriter->SetInput(originalImage); - - imageWriter->SetFileName("test_image"); - imageWriter->SetExtension(".pic"); - imageWriter->Write(); - } - catch ( std::exception& e ) - { - std::cerr << "Error during attempt to write 'test_image.pic' Exception says:" << std::endl; - std::cerr << e.what() << std::endl; - ++numberFailed; - continue; - } - - // load - try - { - mitk::PicFileReader::Pointer imageReader = mitk::PicFileReader::New(); - - imageReader->SetFileName("test_image.pic"); - imageReader->Update(); - - secondImage = imageReader->GetOutput(); - } - catch ( std::exception& e ) - { - std::cerr << "Error during attempt to read 'test_image.pic' Exception says:" << std::endl; - std::cerr << e.what() << std::endl; - ++numberFailed; - continue; - } - - if (secondImage.IsNull()) - { - std::cerr << "Error reading 'test_image.pic'. No image created." << std::endl; - ++numberFailed; - continue; - } - - std::remove( "test_image.pic" ); - - // compare - - bool identical(false); - AccessFixedDimensionByItk_2( secondImage.GetPointer(), ItkImageProcessing, 3, originalImage.GetPointer(), identical ); - - if (!identical) - { - std::cerr << "Images differ for testimage " << i << std::endl; - ++numberFailed; - continue; - } - } - - // if one fails, whole test fails - if (numberFailed > 0) - { - std::cout << "[FAILED]: " << numberFailed << " of " << numberOfTestImages << " sub-tests failed." << std::endl; - return EXIT_FAILURE; - } - else - { - std::cout << "[PASSED]" << std::endl; - return EXIT_SUCCESS; - } -} - diff --git a/Modules/IpPicSupport/Testing/mitkPicFileReaderTest.cpp b/Modules/IpPicSupport/Testing/mitkPicFileReaderTest.cpp deleted file mode 100644 index 2660661c04..0000000000 --- a/Modules/IpPicSupport/Testing/mitkPicFileReaderTest.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/*=================================================================== - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center, -Division of Medical and Biological Informatics. -All rights reserved. - -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. - -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ - -#include "mitkTestingMacros.h" - -#include "mitkImage.h" -#include "mitkPicFileReader.h" -#include "mitkPicHelper.h" -#include "mitkSlicedGeometry3D.h" -#include -#include -#include - -#include -int mitkPicFileReaderTest(int argc, char* argv[]) -{ - MITK_TEST_BEGIN(mitkPicFileReaderTest) - - if(argc>=1) - { - if(itksys::SystemTools::FileLength(argv[1]) == 0) - { - mitk::PicFileReader::Pointer emptyFileReader = mitk::PicFileReader::New(); - emptyFileReader->SetFileName(argv[1]); - MITK_TEST_FOR_EXCEPTION(itk::ImageFileReaderException,emptyFileReader->Update()); - } - else - { - //independently read header of pic file - mitkIpPicDescriptor *picheader=NULL; - if(itksys::SystemTools::LowerCase(itksys::SystemTools::GetFilenameExtension(argv[1])).find(".pic")!=std::string::npos) - { - picheader = mitkIpPicGetHeader(argv[1], NULL); - } - if(picheader==NULL) - { - std::cout<<"file not found/not a pic-file - test not applied [PASSED]"<SetFileName(argv[1]); - reader->Update(); - - std::cout << "Testing IsInitialized(): "; - if(reader->GetOutput()->IsInitialized()==false) - { - std::cout<<"[FAILED]"<GetOutput()->IsSliceSet(0)==false) - { - std::cout<<"[FAILED]"<GetOutput()->GetGeometry()==NULL) - { - std::cout<<"[FAILED]"<GetOutput()->GetTimeGeometry(); - if(timeGeometry==NULL) - { - std::cout<<"[FAILED]"<GetGeometryForTimeStep(0).IsNull()) - { - std::cout<<"[FAILED]"<(timeGeometry->GetGeometryForTimeStep(0).GetPointer()); - if(slicedgeometry==NULL) - { - std::cout<<"[FAILED]"<GetPlaneGeometry(0); - if(geometry2d==NULL) - { - std::cout<<"[FAILED]"<GetExtent(0)-picheader->n[0])>mitk::eps) || (fabs(geometry2d->GetExtent(1)-picheader->n[1])>mitk::eps)) - { - std::cout<<"[FAILED]"<GetExtent(0)-picheader->n[0])>mitk::eps) || (fabs(slicedgeometry->GetExtent(1)-picheader->n[1])>mitk::eps) - || (picheader->dim>2 && (fabs(slicedgeometry->GetExtent(2)-picheader->n[2])>mitk::eps)) - ) - { - std::cout<<"[FAILED]"<GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(0).two_norm(); - spacing[1] = slicedgeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(1).two_norm(); - spacing[2] = slicedgeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(2).two_norm(); - mitk::Vector3D readspacing=slicedgeometry->GetSpacing(); - mitk::Vector3D dist = spacing-readspacing; - if(dist.GetSquaredNorm()>mitk::eps) - { - std::cout<<"[FAILED]"<mitk::eps) - { - std::cout<<"[FAILED]"<dim==4) - { - std::cout << "4D dataset: Testing that timebounds are not infinite: "; - if((timeGeometry->GetTimeBounds(0)[0] == itk::NumericTraits::NonpositiveMin()) && - (timeGeometry->GetTimeBounds(0)[1] == itk::NumericTraits::max()) - ) - { - std::cout<<"[FAILED]"<SetInputImage(image); - myPicFileWriter->SetFileName("/usr/bin"); - myPicFileWriter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - } - catch(...) { - std::cout << "Success: Writer warns on NULL image." << std::endl; - } - - mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New(); - try - { - std::cout<SetFileName( argv[1] ); - factory->Update(); - - if(factory->GetNumberOfOutputs()<1) - { - std::cout<<"file could not be loaded [FAILED]"<GetOutput( 0 ); - image = dynamic_cast(node->GetData()); - if(image.IsNull()) - { - std::cout<<"file "<< argv[1]<< "is not an image - test will not be applied [PASSED]"<SetInputImage(image); - myPicFileWriter->SetFileName("/usr/bin"); - myPicFileWriter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - } - catch(...) { - //this means that a wrong exception (i.e. no itk:Exception) has been thrown - std::cout << "Wrong exception (i.e. no itk:Exception) caught during write [FAILED]" << std::endl; - return EXIT_FAILURE; - } - - unsigned char data_channel1[8] = {0,1,2,3,4,5,6,7}; - unsigned char data_channel2[8] = {10,11,12,13,14,15,16,17}; - - unsigned int dims[2] = {4,2}; - - // create a two-channel test image - mitk::Image::Pointer mcImage = mitk::Image::New(); - mcImage->Initialize( mitk::MakeScalarPixelType(), 2, dims, 2); - mcImage->SetChannel( data_channel1, 0); - mcImage->SetChannel( data_channel2, 1); - - - // create a file name that can be saved so that the writer does not throw exception because of unwriteable location - std::string filename = std::string( MITK_TEST_OUTPUT_DIR ) + "MultiChannel.pic"; - - MITK_TEST_CONDITION_REQUIRED(mcImage.IsNotNull(),"The multi-channel image for testing is not NULL") - - try{ - // test for exception handling - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - - mitk::PicFileWriter::Pointer myPicFileWriter2 = mitk::PicFileWriter::New(); - - myPicFileWriter2->SetInputImage(mcImage); - myPicFileWriter2->SetFileName(filename); - myPicFileWriter2->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - } - catch(...) { - //this means that a wrong exception (i.e. no itk:Exception) has been thrown - std::cout << "Wrong exception (i.e. no itk:Exception) caught during write [FAILED]" << std::endl; - return EXIT_FAILURE; - } - - // always end with this! - MITK_TEST_END() -} - diff --git a/Modules/IpPicSupport/files.cmake b/Modules/IpPicSupport/files.cmake deleted file mode 100644 index 416dcb4632..0000000000 --- a/Modules/IpPicSupport/files.cmake +++ /dev/null @@ -1,9 +0,0 @@ -set(CPP_FILES - mitkIpPicGet.c - mitkPicFileWriter.cpp - mitkPicFileReader.cpp - mitkPicFileIOFactory.cpp - mitkPicHelper.cpp - mitkPicVolumeTimeSeriesIOFactory.cpp - mitkPicVolumeTimeSeriesReader.cpp -) diff --git a/Modules/IpPicSupport/mitkIpPicGet.c b/Modules/IpPicSupport/mitkIpPicGet.c deleted file mode 100755 index 72031b26e6..0000000000 --- a/Modules/IpPicSupport/mitkIpPicGet.c +++ /dev/null @@ -1,646 +0,0 @@ -/***************************************************************************** - - Copyright (c) 1993-2000, Div. Medical and Biological Informatics, - Deutsches Krebsforschungszentrum, Heidelberg, Germany - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - - All advertising materials mentioning features or use of this software must - display the following acknowledgement: - - "This product includes software developed by the Div. Medical and - Biological Informatics, Deutsches Krebsforschungszentrum, Heidelberg, - Germany." - - - Neither the name of the Deutsches Krebsforschungszentrum nor the names of - its contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE DIVISION MEDICAL AND BIOLOGICAL - INFORMATICS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE DIVISION MEDICAL AND BIOLOGICAL INFORMATICS, - THE DEUTSCHES KREBSFORSCHUNGSZENTRUM OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - Send comments and/or bug reports to: - mbi-software@dkfz-heidelberg.de - -*****************************************************************************/ - - -/* - * $RCSfile$ - *-------------------------------------------------------------------- - * DESCRIPTION - * reads a PicFile from disk - * - * $Log$ - * Revision 1.11 2006/09/18 13:55:50 nolden - * FIX: removed define USE_ITKZLIB, crashes on windows - * - * Revision 1.10 2006/09/18 12:57:40 nolden - * CHG: added USE_ITKZLIB define - * - * Revision 1.9 2006/09/15 17:29:57 nolden - * CHG: simplified ipPic include for non-plugin builds - * - * Revision 1.8 2006/01/10 16:53:09 hasselberg - * FIX: ANSI C conformance (required for MSVC7.0) - * - * Revision 1.7 2005/12/21 08:28:42 max - * FIX: renamed ipSize_t to size_t, since ipSize_t is only available in the 64Bit branch op ipPic. - * - * Revision 1.6 2005/12/20 12:56:35 max - * ENH: Added possibility to read beyond 2GB limit. - * - * Revision 1.5 2005/10/19 11:19:43 ivo - * ENH: Chili ipPic compatibility - * - * Revision 1.4 2005/10/13 11:21:12 ivo - * FIX: linker warning (unused var) - * - * Revision 1.3 2005/10/13 08:35:47 ivo - * FIX: warnings - * - * Revision 1.2 2005/10/13 07:52:55 max - * fixed warnings Algorithms/mitkImageFilters/mitkImageToSurfaceFilter.h Algorithms/mitkImageFilters/mitkManualSegmentationToSurfaceFilter.h Algorithms/mitkImageIO/mitkIpPicGet.c - * - * Revision 1.1 2005/10/12 19:08:51 ivo - * ADD: substitute for mitkIpPicGet: original always deletes data pointer and re-allocs it using malloc, which is not compatible with mitk::ImageDataItem. - * - * Revision 1.16 2004/01/16 22:11:59 andre - * big endian bug fix - * - * Revision 1.15 2002/11/13 17:53:00 ivo - * new ipPic added. - * - * Revision 1.13 2002/02/27 09:02:56 andre - * zlib changes - * - * Revision 1.12 2002/02/27 08:54:43 andre - * zlib changes - * - * Revision 1.11 2000/05/04 12:52:37 ivo - * inserted BSD style license - * - * Revision 1.10 2000/02/16 14:29:20 andre - * *** empty log message *** - * - * Revision 1.9 1999/11/28 18:22:42 andre - * *** empty log message *** - * - * Revision 1.8 1999/11/28 16:29:43 andre - * *** empty log message *** - * - * Revision 1.7 1999/11/27 20:03:48 andre - * *** empty log message *** - * - * Revision 1.6 1999/11/27 19:29:43 andre - * *** empty log message *** - * - * Revision 1.5 1998/09/04 17:45:54 andre - * *** empty log message *** - * - * Revision 1.4 1998/05/06 14:13:15 andre - * added info->pixel_start_in_file - * - * Revision 1.3 1997/10/20 13:35:39 andre - * *** empty log message *** - * - * Revision 1.2 1997/09/15 13:21:13 andre - * switched to new what string format - * - * Revision 1.1.1.1 1997/09/06 19:09:59 andre - * initial import - * - * Revision 0.1 1993/04/02 16:18:39 andre - * now works on PC, SUN and DECstation - * - * Revision 0.0 1993/03/26 12:56:26 andre - * Initial revision, NO error checking - * - * - *-------------------------------------------------------------------- - * COPYRIGHT (c) 1993 by DKFZ (Dept. MBI) Heidelberg, FRG - */ - -#ifdef CHILIPLUGIN -#include - -mitkIpPicDescriptor * -MITKipPicGetTags( char *infile_name, mitkIpPicDescriptor *pic ) -{ - return mitkIpPicGetTags(infile_name, pic); -} - -_mitkIpPicTagsElement_t * -_MITKipPicReadTags( _mitkIpPicTagsElement_t *head, mitkIpUInt4_t bytes_to_read, FILE *stream, char encryption_type ) -{ - return _mitkIpPicReadTags(head, bytes_to_read, stream, encryption_type); -} - -//mitkIpPicDescriptor * _MITKipPicOldGet( FILE *infile, mitkIpPicDescriptor *pic ) -//{ -// return _mitkIpPicOldGet(infile, pic); -//} - -mitkIpPicDescriptor * -MITKipPicGet( char *infile_name, mitkIpPicDescriptor *pic ) -{ - if(pic != NULL) - { - mitkIpPicDescriptor * tmpPic; - size_t sizePic, sizeTmpPic; - tmpPic = mitkIpPicGet(infile_name, NULL); - sizePic = _mitkIpPicSize(pic); - sizeTmpPic = _mitkIpPicSize(tmpPic); - if(sizePic != sizeTmpPic) - { - fprintf( stderr, "Critical: MITKipPicGet was given a pic with wrong size\n" ); - return tmpPic; - } - memcpy(pic->data, tmpPic->data, sizePic); - pic->info->tags_head = tmpPic->info->tags_head; - tmpPic->info->tags_head = NULL; - mitkIpPicFree(tmpPic); - return pic; - } - else - return mitkIpPicGet(infile_name, pic); -} - -#else - -#include "mitkIpPic.h" -#ifdef DOS -#include "mitkIpPicOP.h" -#else -#include "mitkIpPicOldP.h" -#endif - -char * MITKstrdup (const char * string) -{ - char *memory; - - if (string==NULL) - return NULL; - - if ( ( memory = (char*)malloc(strlen(string) + 1) ) ) - return strcpy(memory,string); - - return NULL; -} - -_mitkIpPicTagsElement_t * -_MITKipPicReadTags( _mitkIpPicTagsElement_t *head, mitkIpUInt4_t bytes_to_read, FILE *stream, char encryption_type ); - -mitkIpPicDescriptor * _MITKipPicOldGet( FILE *infile, mitkIpPicDescriptor *pic ) -{ - _mitkIpPicOldHeader old_pic; - - size_t elements; - - size_t size = 0; - - size_t number_of_elements; - size_t bytes_per_element; - size_t number_of_bytes; - size_t block_size; - size_t number_of_blocks; - size_t remaining_bytes; - size_t bytes_read; - size_t block_nr; - - size_t ignored; - - mitkIpUInt1_t* data; - - if( pic == NULL ) - pic = mitkIpPicNew(); - else - { - size= _mitkIpPicSize(pic); - if(pic->data == NULL) - size = 0; - } - - /* read infile */ - ignored = mitkIpFReadLE( &(old_pic.dummy1), sizeof(mitkIpUInt4_t), 4, infile ); - if( old_pic.conv <= 0 || old_pic.conv > 6 ) - { - old_pic.conv = 3; - old_pic.rank = 2; - } - - ignored = mitkIpFReadLE( &(old_pic.n1), sizeof(mitkIpUInt4_t), old_pic.rank, infile ); - if( old_pic.rank == 3 && old_pic.n3 == 1 ) - old_pic.rank = 2; - - ignored = mitkIpFReadLE( &(old_pic.type), sizeof(mitkIpUInt4_t), 3, infile ); - if( old_pic.ntxt ) - { - fseek( infile, old_pic.ltxt, SEEK_CUR ); - } - - - elements = old_pic.n1 * old_pic.n2; - if( old_pic.rank == 3 ) - elements *= old_pic.n3; - - if((size == 0) || (size != _mitkIpPicSize(pic))) - { - if( pic->data != NULL ) - { - free( pic->data ); - pic->data = NULL; - } - pic->data = malloc( _mitkIpPicSize(pic) ); - } - - /* - * data is read in blocks of size 'block_size' to prevent from - * errors due to large file sizes (>=2GB) - */ - number_of_elements = elements; - bytes_per_element = old_pic.type; - number_of_bytes = number_of_elements * bytes_per_element; - block_size = 1024*1024; /* Use 1 MB blocks. Make sure that block size is smaller than 2^31 */ - number_of_blocks = number_of_bytes / block_size; - remaining_bytes = number_of_bytes % block_size; - bytes_read = 0; - block_nr = 0; - - data = (mitkIpUInt1_t*) pic->data; - for ( block_nr = 0 ; block_nr < number_of_blocks ; ++block_nr ) - bytes_read += mitkIpPicFReadLE( data + ( block_nr * block_size ), 1, (unsigned int) block_size, infile ); - bytes_read += mitkIpPicFReadLE( data + ( number_of_blocks * block_size ), 1, (unsigned int) remaining_bytes, infile ); - - if ( bytes_read != number_of_bytes ) - fprintf( stderr, "Error while reading (ferror indicates %u), only %lu bytes were read! Eof indicator is %u.\n", ferror(infile), (long unsigned int)bytes_read, feof(infile) ); - - /* convert to the new pic3 format */ - - if( old_pic.type == 1 ) - pic->type = mitkIpPicUInt; - else - pic->type = (mitkIpPicType_t)old_pic.conv; - pic->bpe = old_pic.type*8; - pic->dim = old_pic.rank; - pic->n[0] = old_pic.n1; - pic->n[1] = old_pic.n2; - pic->n[2] = old_pic.n3; - pic->n[3] = old_pic.n4; - pic->n[4] = old_pic.n5; - pic->n[5] = old_pic.n6; - pic->n[6] = old_pic.n7; - pic->n[7] = old_pic.n8; - - return( pic ); -} - -mitkIpUInt4_t _MITKipPicTSVElements( mitkIpPicTSV_t *tsv ) -{ - mitkIpUInt4_t i; - mitkIpUInt4_t elements; - - if( tsv->dim == 0 ) - return( 0 ); - - elements = tsv->n[0]; - for( i = 1; i < tsv->dim; i++ ) - elements *= tsv->n[i]; - - return( elements ); -} - - -_mitkIpPicTagsElement_t * -_MITKipPicReadTags( _mitkIpPicTagsElement_t *head, mitkIpUInt4_t bytes_to_read, FILE *stream, char encryption_type ) -{ - while( bytes_to_read > 0 ) - { - mitkIpPicTSV_t *tsv; - - mitkIpPicTag_t tag_name; - mitkIpUInt4_t len; - - size_t ignored; - - /*printf( "bytes_to_read: %i\n", bytes_to_read ); */ - - tsv = malloc( sizeof(mitkIpPicTSV_t) ); - - ignored = mitkIpPicFRead( &tag_name, 1, sizeof(mitkIpPicTag_t), stream ); - strncpy( tsv->tag, tag_name, _mitkIpPicTAGLEN ); - tsv->tag[_mitkIpPicTAGLEN] = '\0'; - - ignored = mitkIpPicFReadLE( &len, sizeof(mitkIpUInt4_t), 1, stream ); - - ignored = mitkIpPicFReadLE( &(tsv->type), sizeof(mitkIpUInt4_t), 1, stream ); - ignored = mitkIpPicFReadLE( &(tsv->bpe), sizeof(mitkIpUInt4_t), 1, stream ); - ignored = mitkIpPicFReadLE( &(tsv->dim), sizeof(mitkIpUInt4_t), 1, stream ); - - - ignored = mitkIpPicFReadLE( &(tsv->n), sizeof(mitkIpUInt4_t), tsv->dim, stream ); - - if( tsv->type == mitkIpPicTSV ) - { - tsv->value = NULL; - tsv->value = _mitkIpPicReadTags( tsv->value, - len - 3 * sizeof(mitkIpUInt4_t) - - tsv->dim * sizeof(mitkIpUInt4_t), - stream, - encryption_type ); - } - else - { - mitkIpUInt4_t elements; - - elements = _MITKipPicTSVElements( tsv ); - - if( tsv->type == mitkIpPicASCII - || tsv->type == mitkIpPicNonUniform ) - tsv->bpe = 8; - -assert( elements * tsv->bpe / 8 == len - - 3 * sizeof(mitkIpUInt4_t) - - tsv->dim * sizeof(mitkIpUInt4_t) ); - - if( tsv->type == mitkIpPicASCII ) - tsv->value = malloc( elements+1 * tsv->bpe / 8 ); - else - tsv->value = malloc( elements * tsv->bpe / 8 ); - - ignored = mitkIpPicFReadLE( tsv->value, tsv->bpe / 8, elements, stream ); - - if( tsv->type == mitkIpPicASCII ) - ((char *)(tsv->value))[elements] = '\0'; - - if( encryption_type == 'e' - && ( tsv->type == mitkIpPicASCII - || tsv->type == mitkIpPicNonUniform ) ) - { - if( tsv->type == mitkIpPicNonUniform ) - { - sprintf( tsv->tag, "*** ENCRYPTED ***" ); - tsv->tag[_mitkIpPicTAGLEN] = '\0'; - } - - free( tsv->value ); - - tsv->value = MITKstrdup( "*** ENCRYPTED ***" ); - tsv->n[0] = (mitkIpUInt4_t)strlen(tsv->value); - tsv->type = mitkIpPicASCII; - tsv->dim = 1; - } - } - - head = _mitkIpPicInsertTag( head, tsv ); - - bytes_to_read -= 32 /* name */ - + sizeof(mitkIpUInt4_t) /* len */ - + len; /* type + bpe + dim + n[] + data */ - } - return( head ); -} - -mitkIpPicDescriptor * -MITKipPicGetTags( char *infile_name, mitkIpPicDescriptor *pic ) -{ - mitkIpPicFile_t infile; - - mitkIpPicTag_t tag_name; - mitkIpUInt4_t dummy; - mitkIpUInt4_t len; - mitkIpUInt4_t dim; - mitkIpUInt4_t n[_mitkIpPicNDIM]; - - mitkIpUInt4_t to_read; - - size_t ignored; - - infile = _mitkIpPicOpenPicFileIn( infile_name ); - - if( infile == NULL ) - { - /*ipPrintErr( "mitkIpPicGetTags: sorry, error opening infile\n" );*/ - return( NULL ); - } - - if( pic != NULL ) - pic->info->write_protect = mitkIpFalse; - - /* read infile */ - ignored = mitkIpPicFRead( &(tag_name[0]), 1, 4, infile ); - - if( strncmp( mitkIpPicVERSION, tag_name, 4 ) != 0 ) - { - if( infile != stdin ) - mitkIpPicFClose( infile ); - return( pic ); - } - - if( pic == NULL ) - pic = mitkIpPicNew(); - - ignored = mitkIpPicFRead( &(tag_name[4]), 1, sizeof(mitkIpPicTag_t)-4, infile ); - /*strncpy( pic->info->version, tag_name, _mitkIpPicTAGLEN );*/ - - ignored = mitkIpPicFReadLE( &len, sizeof(mitkIpUInt4_t), 1, infile ); - - ignored = mitkIpPicFReadLE( &dummy, sizeof(mitkIpUInt4_t), 1, infile ); - ignored = mitkIpPicFReadLE( &dummy, sizeof(mitkIpUInt4_t), 1, infile ); - ignored = mitkIpPicFReadLE( &dim, sizeof(mitkIpUInt4_t), 1, infile ); - - ignored = mitkIpPicFReadLE( n, sizeof(mitkIpUInt4_t), dim, infile ); - - - to_read = len - 3 * sizeof(mitkIpUInt4_t) - - dim * sizeof(mitkIpUInt4_t); - - pic->info->tags_head = _MITKipPicReadTags( pic->info->tags_head, to_read, infile, mitkIpPicEncryptionType(pic) ); - - pic->info->pixel_start_in_file = mitkIpPicFTell( infile ); - - if( infile != stdin ) - mitkIpPicFClose( infile ); - - return( pic ); -} - -mitkIpPicDescriptor * -MITKipPicGet( char *infile_name, mitkIpPicDescriptor *pic ) -{ - mitkIpPicFile_t infile; - - mitkIpPicTag_t tag_name; - mitkIpUInt4_t len; - - mitkIpUInt4_t to_read; - size_t size; - - size_t number_of_elements; - size_t bytes_per_element; - size_t number_of_bytes; - size_t block_size; - size_t number_of_blocks; - size_t remaining_bytes; - size_t bytes_read; - size_t block_nr; - - mitkIpUInt1_t* data; - - size_t ignored; - - infile = _mitkIpPicOpenPicFileIn( infile_name ); - - if( !infile ) - { - /*ipPrintErr( "mitkIpPicGet: sorry, error opening infile\n" );*/ - return( NULL ); - } - - /* read infile */ - ignored = mitkIpPicFRead( tag_name, 1, 4, infile ); - - if( strncmp( "\037\213", tag_name, 2 ) == 0 ) - { - fprintf( stderr, "mitkIpPicGetHeader: sorry, can't read compressed file\n" ); - return( NULL ); - } - else if( strncmp( mitkIpPicVERSION, tag_name, 4 ) != 0 ) - { -#ifndef CHILIPLUGIN - if( pic == NULL ) - pic = _MITKipPicOldGet( infile, - NULL ); - else - _MITKipPicOldGet( infile, - pic ); - if( infile != stdin ) - mitkIpPicFClose( infile ); -#else - return NULL; -#endif - return( pic ); - } - - size = 0; - if( pic == NULL ) - pic = mitkIpPicNew(); - else - { - size= _mitkIpPicSize(pic); - if(pic->data == NULL) - size = 0; - } - - if( pic->info != NULL ) - { - _mitkIpPicFreeTags( pic->info->tags_head ); - pic->info->tags_head = NULL; - } - - ignored = mitkIpPicFRead( &(tag_name[4]), 1, sizeof(mitkIpPicTag_t)-4, infile ); - strncpy( pic->info->version, tag_name, _mitkIpPicTAGLEN ); - - ignored = mitkIpPicFReadLE( &len, sizeof(mitkIpUInt4_t), 1, infile ); - - ignored = mitkIpPicFReadLE( &(pic->type), sizeof(mitkIpUInt4_t), 1, infile ); - ignored = mitkIpPicFReadLE( &(pic->bpe), sizeof(mitkIpUInt4_t), 1, infile ); - ignored = mitkIpPicFReadLE( &(pic->dim), sizeof(mitkIpUInt4_t), 1, infile ); - - ignored = mitkIpPicFReadLE( &(pic->n), sizeof(mitkIpUInt4_t), pic->dim, infile ); - - (void *)ignored; - - to_read = len - 3 * sizeof(mitkIpUInt4_t) - - pic->dim * sizeof(mitkIpUInt4_t); -#if 0 - mitkIpPicFSeek( infile, to_read, SEEK_CUR ); -#else - pic->info->tags_head = _MITKipPicReadTags( pic->info->tags_head, to_read, infile, mitkIpPicEncryptionType(pic) ); -#endif - - pic->info->write_protect = mitkIpFalse; - - if((size == 0) || (size != _mitkIpPicSize(pic))) - { - if( pic->data != NULL ) - { - free( pic->data ); - pic->data = NULL; - } -#ifdef WIN - if ((pic->hdata = GlobalAlloc( GMEM_MOVEABLE, _mitkIpPicSize(pic) )) != 0) - pic->data = GlobalLock( pic->hdata ); -#else - pic->data = malloc( _mitkIpPicSize(pic) ); -#endif - } - - pic->info->pixel_start_in_file = mitkIpPicFTell( infile ); - /* - * data is read in blocks of size 'block_size' to prevent from - * errors due to large file sizes (>=2GB) - */ - number_of_elements = _mitkIpPicElements(pic); - bytes_per_element = pic->bpe / 8; - number_of_bytes = number_of_elements * bytes_per_element; - block_size = 1024*1024; /* Use 1 MB blocks. Make sure that block size is smaller than 2^31 */ - number_of_blocks = number_of_bytes / block_size; - remaining_bytes = number_of_bytes % block_size; - bytes_read = 0; - block_nr = 0; - /*printf( "mitkIpPicGet: number of blocks to read is %ul.\n", number_of_blocks ); */ - - data = (mitkIpUInt1_t*) pic->data; - if( pic->type == mitkIpPicNonUniform ) - { - for ( block_nr = 0 ; block_nr < number_of_blocks ; ++block_nr ) - bytes_read += mitkIpPicFRead( data + ( block_nr * block_size ), 1, (unsigned int) block_size, infile ); - bytes_read += mitkIpPicFRead( data + ( number_of_blocks * block_size ), 1, (unsigned int) remaining_bytes, infile ); - } - else - { - for ( block_nr = 0 ; block_nr < number_of_blocks ; ++block_nr ) - bytes_read += mitkIpPicFReadLE( data + ( block_nr * block_size ), 1, (unsigned int) block_size, infile ); - bytes_read += mitkIpPicFReadLE( data + ( number_of_blocks * block_size ), 1, (unsigned int) remaining_bytes, infile ); - } - - if ( bytes_read != number_of_bytes ) - { - fprintf( stderr, "Error while reading, only %lu bytes were read! Eof indicator is %u.\n", (long unsigned int)bytes_read, mitkIpPicFEOF(infile) ); -#ifndef USE_ZLIB - fprintf( stderr, "(ferror indicates %u).\n", ferror(infile)); -#endif - } - - if( infile != stdin ) - mitkIpPicFClose( infile ); - -#ifdef WIN - GlobalUnlock( pic->hdata ); -#endif - - return( pic ); -} - -#endif // CHILIPLUGIN diff --git a/Modules/IpPicSupport/mitkPicFileIOFactory.cpp b/Modules/IpPicSupport/mitkPicFileIOFactory.cpp deleted file mode 100644 index f9858b8f20..0000000000 --- a/Modules/IpPicSupport/mitkPicFileIOFactory.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/*=================================================================== - -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 "mitkPicFileIOFactory.h" -#include "mitkIOAdapter.h" -#include "mitkPicFileReader.h" -#include "mitkCoreObjectFactory.h" - -#include "itkVersion.h" - - -namespace mitk -{ -PicFileIOFactory::PicFileIOFactory() -{ - this->RegisterOverride("mitkIOAdapter", - "mitkPicFileReader", - "mitk Pic Image IO", - 1, - itk::CreateObjectFunction >::New()); -} - -PicFileIOFactory::~PicFileIOFactory() -{ -} - -const char* PicFileIOFactory::GetITKSourceVersion() const -{ - return ITK_SOURCE_VERSION; -} - -const char* PicFileIOFactory::GetDescription() const -{ - return "PicFile IO Factory, allows the loading of DKFZ Pic images"; -} - -} // end namespace mitk - -struct RegisterIpPicIOFactory{ - RegisterIpPicIOFactory() - : m_Factory( mitk::PicFileIOFactory::New() ) - { - MITK_DEBUG << "Registering PicFileIOFactory "; - itk::ObjectFactoryBase::RegisterFactory( m_Factory ); - } - - ~RegisterIpPicIOFactory() - { - itk::ObjectFactoryBase::UnRegisterFactory( m_Factory ); - } - - mitk::PicFileIOFactory::Pointer m_Factory; -}; - -static RegisterIpPicIOFactory registerIpPicIOFactory; diff --git a/Modules/IpPicSupport/mitkPicFileIOFactory.h b/Modules/IpPicSupport/mitkPicFileIOFactory.h deleted file mode 100644 index da9f1ae769..0000000000 --- a/Modules/IpPicSupport/mitkPicFileIOFactory.h +++ /dev/null @@ -1,74 +0,0 @@ -/*=================================================================== - -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 __mitkPicFileIOFactory_h -#define __mitkPicFileIOFactory_h - -#ifdef _MSC_VER -#pragma warning ( disable : 4786 ) -#endif - -#include -#include "itkObjectFactoryBase.h" -#include "mitkBaseData.h" - -namespace mitk -{ -//##Documentation -//## @brief Create instances of PicFileReader objects using an object factory. -//## -//## @ingroup IO -class MitkIpPicSupport_EXPORT PicFileIOFactory : public itk::ObjectFactoryBase -{ -public: - /** Standard class typedefs. */ - typedef PicFileIOFactory Self; - typedef itk::ObjectFactoryBase Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; - - /** Class methods used to interface with the registered factories. */ - virtual const char* GetITKSourceVersion(void) const; - virtual const char* GetDescription(void) const; - - /** Method for class instantiation. */ - itkFactorylessNewMacro(Self); - static PicFileIOFactory* FactoryNew() { return new PicFileIOFactory;} - /** Run-time type information (and related methods). */ - itkTypeMacro(PicFileIOFactory, ObjectFactoryBase); - - /** Register one factory of this type */ -/* static void RegisterOneFactory(void) - { - std::cout << "Register PicFile Factory."; - - PicFileIOFactory::Pointer PicFileIOFactory = PicFileIOFactory::New(); - ObjectFactoryBase::RegisterFactory(PicFileIOFactory); - } -*/ -protected: - PicFileIOFactory(); - ~PicFileIOFactory(); - -private: - PicFileIOFactory(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented - -}; - - -} // end namespace mitk - -#endif diff --git a/Modules/IpPicSupport/mitkPicFileReader.cpp b/Modules/IpPicSupport/mitkPicFileReader.cpp deleted file mode 100644 index 3a021d419a..0000000000 --- a/Modules/IpPicSupport/mitkPicFileReader.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/*=================================================================== - -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 "mitkPicFileReader.h" -#include "mitkPicHelper.h" -#include -#include "mitkImageWriteAccessor.h" - -extern "C" -{ - mitkIpPicDescriptor * MITKipPicGet( char *infile_name, mitkIpPicDescriptor *pic ); - mitkIpPicDescriptor * MITKipPicGetTags( char *infile_name, mitkIpPicDescriptor *pic ); -} - -void mitk::PicFileReader::GenerateOutputInformation() -{ - Image::Pointer output = this->GetOutput(); - - if ((output->IsInitialized()) && (this->GetMTime() <= m_ReadHeaderTime.GetMTime())) - return; - - itkDebugMacro(<<"Reading file for GenerateOutputInformation()" << m_FileName); - - // Check to see if we can read the file given the name or prefix - // - if ( m_FileName == "" && m_FilePrefix == "" ) - { - throw itk::ImageFileReaderException(__FILE__, __LINE__, "One of FileName or FilePrefix must be non-empty"); - } - - if( m_FileName != "") - { - mitkIpPicDescriptor* header=mitkIpPicGetHeader(const_cast(m_FileName.c_str()), NULL); - - if ( !header ) - { - throw itk::ImageFileReaderException(__FILE__, __LINE__, "File could not be read."); - } - - header=MITKipPicGetTags(const_cast(m_FileName.c_str()), header); - - int channels = 1; - - mitkIpPicTSV_t *tsv; - if ( (tsv = mitkIpPicQueryTag( header, "SOURCE HEADER" )) != NULL) - { - if(tsv->n[0]>1e+06) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag( header, "SOURCE HEADER" ); - mitkIpPicFreeTag(tsvSH); - } - } - if ( (tsv = mitkIpPicQueryTag( header, "ICON80x80" )) != NULL) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag( header, "ICON80x80" ); - mitkIpPicFreeTag(tsvSH); - } - if ( (tsv = mitkIpPicQueryTag( header, "VELOCITY" )) != NULL) - { - ++channels; - mitkIpPicDelTag( header, "VELOCITY" ); - } - - if( header == NULL || header->bpe == 0) - { - itk::ImageFileReaderException e(__FILE__, __LINE__); - std::ostringstream msg; - msg << " Could not read file " - << m_FileName.c_str(); - e.SetDescription(msg.str().c_str()); - throw e; - return; - } - - // if pic image only 2D, the n[2] value is not initialized - unsigned int slices = 1; - if( header->dim == 2 ) - header->n[2] = slices; - - // First initialize the geometry of the output image by the pic-header - SlicedGeometry3D::Pointer slicedGeometry = mitk::SlicedGeometry3D::New(); - PicHelper::InitializeEvenlySpaced(header, header->n[2], slicedGeometry); - - // if pic image only 3D, the n[3] value is not initialized - unsigned int timesteps = 1; - if( header->dim > 3 ) - timesteps = header->n[3]; - - slicedGeometry->ImageGeometryOn(); - ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); - timeGeometry->Initialize(slicedGeometry, timesteps); - - // Cast the pic descriptor to ImageDescriptor and initialize the output - - output->Initialize( CastToImageDescriptor(header)); - output->SetTimeGeometry( timeGeometry ); - mitkIpPicFree ( header ); - } - else - { - int numberOfImages=0; - m_StartFileIndex=0; - - mitkIpPicDescriptor* header=NULL; - - char fullName[1024]; - - while(m_StartFileIndex<10) - { - sprintf(fullName, m_FilePattern.c_str(), m_FilePrefix.c_str(), m_StartFileIndex+numberOfImages); - FILE * f=fopen(fullName,"r"); - if(f==NULL) - { - //already found an image? - if(numberOfImages>0) - break; - //no? let's increase start - ++m_StartFileIndex; - } - else - { - fclose(f); - //only open the header of the first file found, - //@warning what to do when images do not have the same size?? - if(header==NULL) - { - header=mitkIpPicGetHeader(fullName, NULL); - header=MITKipPicGetTags(fullName, header); - } - ++numberOfImages; - } - } - - printf("\n numberofimages %d\n",numberOfImages); - - if(numberOfImages==0) - { - itk::ImageFileReaderException e(__FILE__, __LINE__); - std::ostringstream msg; - msg << "no images found"; - e.SetDescription(msg.str().c_str()); - throw e; - return; - } - - //@FIXME: was ist, wenn die Bilder nicht alle gleich gross sind? - if(numberOfImages>1) - { - printf("\n numberofimages %d > 1\n",numberOfImages); - header->dim=3; - header->n[2]=numberOfImages; - } - - printf(" \ninitialisize output\n"); - output->Initialize( CastToImageDescriptor(header) ); - mitkIpPicFree ( header ); - } - - m_ReadHeaderTime.Modified(); -} - -void mitk::PicFileReader::ConvertHandedness(mitkIpPicDescriptor* pic) -{ - //left to right handed conversion - if(pic->dim>=3) - { - mitkIpPicDescriptor* slice=mitkIpPicCopyHeader(pic, NULL); - slice->dim=2; - size_t size=_mitkIpPicSize(slice); - slice->data=malloc(size); - - size_t v, volumes = (pic->dim>3? pic->n[3] : 1); - size_t volume_size = size*pic->n[2]; - - for(v=0; vdata; - unsigned char *p_last=(unsigned char *)pic->data; - p_first+=v*volume_size; - p_last+=size*(pic->n[2]-1)+v*volume_size; - - size_t i, smid=pic->n[2]/2; - for(i=0; idata, p_last, size); - memcpy(p_last, p_first, size); - memcpy(p_first, slice->data, size); - } - } - mitkIpPicFree(slice); - } -} - -void mitk::PicFileReader::GenerateData() -{ - Image::Pointer output = this->GetOutput(); - - // Check to see if we can read the file given the name or prefix - // - if ( m_FileName == "" && m_FilePrefix == "" ) - { - throw itk::ImageFileReaderException(__FILE__, __LINE__, "One of FileName or FilePrefix must be non-empty"); - } - - if( m_FileName != "") - { - mitkIpPicDescriptor* outputPic = mitkIpPicNew(); - mitk::ImageWriteAccessor imageAccess(output); - outputPic = CastToIpPicDescriptor(output, &imageAccess, outputPic); - mitkIpPicDescriptor* pic=MITKipPicGet(const_cast(m_FileName.c_str()), - outputPic); - // comes upside-down (in MITK coordinates) from PIC file - ConvertHandedness(pic); - - mitkIpPicTSV_t *tsv; - if ( (tsv = mitkIpPicQueryTag( pic, "SOURCE HEADER" )) != NULL) - { - if(tsv->n[0]>1e+06) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag( pic, "SOURCE HEADER" ); - mitkIpPicFreeTag(tsvSH); - } - } - if ( (tsv = mitkIpPicQueryTag( pic, "ICON80x80" )) != NULL) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag( pic, "ICON80x80" ); - mitkIpPicFreeTag(tsvSH); - } - if ( (tsv = mitkIpPicQueryTag( pic, "VELOCITY" )) != NULL) - { - mitkIpPicDescriptor* header = mitkIpPicCopyHeader(pic, NULL); - header->data = tsv->value; - ConvertHandedness(header); - output->SetChannel(header->data, 1); - header->data = NULL; - mitkIpPicFree(header); - mitkIpPicDelTag( pic, "VELOCITY" ); - } - - //slice-wise reading - //currently much too slow. - //else - //{ - // int sstart, smax; - // int tstart, tmax; - - // sstart=output->GetRequestedRegion().GetIndex(2); - // smax=sstart+output->GetRequestedRegion().GetSize(2); - - // tstart=output->GetRequestedRegion().GetIndex(3); - // tmax=tstart+output->GetRequestedRegion().GetSize(3); - - // int s,t; - // for(s=sstart; s(m_FileName.c_str()), NULL, t*smax+s+1); - // output->SetPicSlice(pic,s,t); - // } - // } - //} - } - else - { - int position; - mitkIpPicDescriptor* pic=NULL; - - int zDim=(output->GetDimension()>2?output->GetDimensions()[2]:1); - printf("\n zdim is %u \n",zDim); - - for (position = 0; position < zDim; ++position) - { - char fullName[1024]; - - sprintf(fullName, m_FilePattern.c_str(), m_FilePrefix.c_str(), m_StartFileIndex+position); - - pic=MITKipPicGet(fullName, pic); - if(pic==NULL) - { - itkDebugMacro("Pic file '" << fullName << "' does not exist."); - } - /* FIXME else - if(output->SetPicSlice(pic, position)==false) - { - itkDebugMacro("Image '" << fullName << "' could not be added to Image."); - }*/ - } - if(pic!=NULL) - mitkIpPicFree(pic); - } -} - -void mitk::PicFileReader::EnlargeOutputRequestedRegion(itk::DataObject *output) -{ - output->SetRequestedRegionToLargestPossibleRegion(); -} - -bool mitk::PicFileReader::CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern) -{ - // First check the extension - if( filename == "" ) - { - //MITK_INFO<<"No filename specified."< -#include "mitkFileReader.h" -#include "mitkImageSource.h" - -#include "mitkIpPic.h" -#include "mitkLegacyAdaptors.h" - - -namespace mitk { -//##Documentation -//## @brief Reader to read files in DKFZ-pic-format -//## @ingroup IO -class MitkIpPicSupport_EXPORT PicFileReader : public ImageSource, public FileReader -{ -public: - mitkClassMacro(PicFileReader, FileReader); - - /** Method for creation through the object factory. */ - itkFactorylessNewMacro(Self) - itkCloneMacro(Self) - - itkSetStringMacro(FileName); - itkGetStringMacro(FileName); - - itkSetStringMacro(FilePrefix); - itkGetStringMacro(FilePrefix); - - itkSetStringMacro(FilePattern); - itkGetStringMacro(FilePattern); - - virtual void EnlargeOutputRequestedRegion(itk::DataObject *output); - - static void ConvertHandedness(mitkIpPicDescriptor* pic); - - static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern); - -protected: - virtual void GenerateData(); - - virtual void GenerateOutputInformation(); - - PicFileReader(); - - ~PicFileReader(); - - //##Description - //## @brief Time when Header was last read - itk::TimeStamp m_ReadHeaderTime; - - int m_StartFileIndex; - - std::string m_FileName; - - std::string m_FilePrefix; - - std::string m_FilePattern; - -}; - -} // namespace mitk - -#endif /* PICFILEREADER_H_HEADER_INCLUDED_C1F48A22 */ - - diff --git a/Modules/IpPicSupport/mitkPicFileWriter.cpp b/Modules/IpPicSupport/mitkPicFileWriter.cpp deleted file mode 100644 index 7eabc40734..0000000000 --- a/Modules/IpPicSupport/mitkPicFileWriter.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/*=================================================================== - -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 "mitkPicFileWriter.h" -#include "mitkPicFileReader.h" - -extern "C" -{ -size_t _mitkIpPicFWrite( const void *ptr, size_t size, size_t nitems, mitkIpPicFile_t stream); -} - -mitk::PicFileWriter::PicFileWriter() -{ - this->SetNumberOfRequiredInputs( 1 ); -} - -mitk::PicFileWriter::~PicFileWriter() -{ -} - -void mitk::PicFileWriter::GenerateData() -{ - if ( m_FileName == "" ) - { - itkWarningMacro( << "Sorry, filename has not been set!" ); - return ; - } - - std::ofstream testfilehandle( m_FileName.c_str(), std::ios::out); - if (!testfilehandle.good()) - { - testfilehandle.close(); - itkExceptionMacro(<<"File location '" << m_FileName << "' not writeable"); - } - else - { - testfilehandle.close(); - } - - Image::Pointer input = const_cast(this->GetInput()); - - if ( input.IsNull() ) - { - itkExceptionMacro(<< "Nothing to write: Input is NULL." ); - } - - if( input->GetNumberOfChannels() > 1) - { - std::cout << "Multiple channel. Cannot write. Will throw..."; - itkExceptionMacro(<< "The PicFileWriter does not support multiple channel data. Nothing will be written." ); - } - - mitkIpPicDescriptor * picImage = mitkIpPicNew(); - mitk::ImageWriteAccessor imageAccess(input); - picImage = CastToIpPicDescriptor(input, &imageAccess, picImage); - - SlicedGeometry3D* slicedGeometry = input->GetSlicedGeometry(); - if (slicedGeometry != NULL) - { - //set tag "REAL PIXEL SIZE" - const Vector3D & spacing = slicedGeometry->GetSpacing(); - mitkIpPicTSV_t *pixelSizeTag; - pixelSizeTag = mitkIpPicQueryTag( picImage, "REAL PIXEL SIZE" ); - if (!pixelSizeTag) - { - pixelSizeTag = (mitkIpPicTSV_t *) malloc( sizeof(mitkIpPicTSV_t) ); - pixelSizeTag->type = mitkIpPicFloat; - pixelSizeTag->bpe = 32; - strcpy(pixelSizeTag->tag, "REAL PIXEL SIZE"); - pixelSizeTag->dim = 1; - pixelSizeTag->n[0] = 3; - pixelSizeTag->value = malloc( sizeof(float) * 3 ); - mitkIpPicAddTag (picImage, pixelSizeTag); - } - ((float*)pixelSizeTag->value)[0] = spacing[0]; - ((float*)pixelSizeTag->value)[1] = spacing[1]; - ((float*)pixelSizeTag->value)[2] = spacing[2]; - //set tag "ISG" - //ISG == offset/origin transformation matrix(matrix) spancings - //ISG == offset0 offset1 offset2 spalte0_0 spalte0_1 spalte0_2 spalte1_0 spalte1_1 spalte1_2 spalte2_0 spalte2_1 spalte2_2 spacing0 spacing1 spacing2 - mitkIpPicTSV_t *geometryTag; - geometryTag = mitkIpPicQueryTag( picImage, "ISG" ); - if (!geometryTag) - { - geometryTag = (mitkIpPicTSV_t *) malloc( sizeof(mitkIpPicTSV_t) ); - geometryTag->type = mitkIpPicFloat; - geometryTag->bpe = 32; - strcpy(geometryTag->tag, "ISG"); - geometryTag->dim = 2; - geometryTag->n[0] = 3; - geometryTag->n[1] = 4; - geometryTag->value = malloc( sizeof(float) * 3 * 4 ); - mitkIpPicAddTag (picImage, geometryTag); - } - const AffineTransform3D::OffsetType& offset = slicedGeometry->GetIndexToWorldTransform()->GetOffset(); - ((float*)geometryTag->value)[0] = offset[0]; - ((float*)geometryTag->value)[1] = offset[1]; - ((float*)geometryTag->value)[2] = offset[2]; - - const AffineTransform3D::MatrixType& matrix = slicedGeometry->GetIndexToWorldTransform()->GetMatrix(); - const AffineTransform3D::MatrixType::ValueType* row0 = matrix[0]; - const AffineTransform3D::MatrixType::ValueType* row1 = matrix[1]; - const AffineTransform3D::MatrixType::ValueType* row2 = matrix[2]; - - Vector3D v; - - FillVector3D(v, row0[0], row1[0], row2[0]); - v.Normalize(); - ((float*)geometryTag->value)[3] = v[0]; - ((float*)geometryTag->value)[4] = v[1]; - ((float*)geometryTag->value)[5] = v[2]; - - FillVector3D(v, row0[1], row1[1], row2[1]); - v.Normalize(); - ((float*)geometryTag->value)[6] = v[0]; - ((float*)geometryTag->value)[7] = v[1]; - ((float*)geometryTag->value)[8] = v[2]; - - ((float*)geometryTag->value)[9] = spacing[0]; - ((float*)geometryTag->value)[10] = spacing[1]; - ((float*)geometryTag->value)[11] = spacing[2]; - } - PicFileReader::ConvertHandedness(picImage); // flip upside-down in MITK coordinates - - // Following line added to detect write errors. If saving .pic files from the plugin is broken again, - // please report a bug, don't just remove this line! - int ret = MITKIpPicPut((char*)(m_FileName.c_str()), picImage); - - if (ret != 0) - { - PicFileReader::ConvertHandedness(picImage); // flip back from upside-down state - throw std::ios_base::failure("Error during .pic file writing in "__FILE__); - } - - PicFileReader::ConvertHandedness(picImage); // flip back from upside-down state -} - -void mitk::PicFileWriter::SetInputImage( Image* image ) -{ - this->ProcessObject::SetNthInput( 0, image ); -} - -const mitk::Image* mitk::PicFileWriter::GetInput() -{ - if ( this->GetNumberOfInputs() < 1 ) - { - MITK_ERROR << "No input image present."; - return NULL; - } - else - { - return static_cast< const Image * >( this->ProcessObject::GetInput( 0 ) ); - } -} - -int mitk::PicFileWriter::MITKIpPicPut( char *outfile_name, mitkIpPicDescriptor *pic ) -{ - FILE* outfile; - - mitkIpUInt4_t len; - mitkIpUInt4_t tags_len; - - if( pic->info->write_protect ) - { - fprintf( stderr, "mitkIpPicPut: sorry, can't write (missing tags !!!)\n" ); - //return( -1 ); - } - - if( mitkIpPicEncryptionType(pic) != ' ' ) - { - fprintf( stderr, "mitkIpPicPut: warning: was encrypted !!!\n" ); - } - - if( outfile_name == NULL ) - outfile = stdout; - else if( strcmp(outfile_name, "stdout") == 0 ) - outfile = stdout; - else - { - mitkIpPicRemoveFile( outfile_name ); - // Removed due to linker problems when compiling - // an mitk chili plugin using msvc: there appear - // unresolved external symbol errors to function - // _ipPicGetWriteCompression() - /* - if( mitkIpPicGetWriteCompression() ) - { - char buff[1024]; - - sprintf( buff, "%s.gz", outfile_name ); - outfile = (FILE*) mitkIpPicFOpen( buff, "wb" ); // cast to prevent warning. - } - else - */ - outfile = fopen( outfile_name, "wb" ); - } - - - if( outfile == NULL ) - { - fprintf( stderr, "mitkIpPicPut: sorry, error opening outfile\n" ); - return( -1 ); - } - - tags_len = _mitkIpPicTagsSize( pic->info->tags_head ); - - len = tags_len + 3 * sizeof(mitkIpUInt4_t) - + pic->dim * sizeof(mitkIpUInt4_t); - - /* write oufile */ - if( mitkIpPicEncryptionType(pic) == ' ' ) - mitkIpPicFWrite( mitkIpPicVERSION, 1, sizeof(mitkIpPicTag_t), outfile ); - else - mitkIpPicFWrite( pic->info->version, 1, sizeof(mitkIpPicTag_t), outfile ); - - mitkIpPicFWriteLE( &len, sizeof(mitkIpUInt4_t), 1, outfile ); - - mitkIpPicFWriteLE( &(pic->type), sizeof(mitkIpUInt4_t), 1, outfile ); - mitkIpPicFWriteLE( &(pic->bpe), sizeof(mitkIpUInt4_t), 1, outfile ); - mitkIpPicFWriteLE( &(pic->dim), sizeof(mitkIpUInt4_t), 1, outfile ); - - mitkIpPicFWriteLE( pic->n, sizeof(mitkIpUInt4_t), pic->dim, outfile ); - - _mitkIpPicWriteTags( pic->info->tags_head, outfile, mitkIpPicEncryptionType(pic) ); - // Removed due to linker problems when compiling - // an mitk chili plugin using msvc: there appear - // unresolved external symbol errors to function - // _ipPicGetWriteCompression() - /* - if( mitkIpPicGetWriteCompression() ) - pic->info->pixel_start_in_file = mitkIpPicFTell( outfile ); - else - */ - pic->info->pixel_start_in_file = ftell( outfile ); - - if( pic->data ) - { - size_t number_of_elements = _mitkIpPicElements(pic); - size_t bytes_per_element = pic->bpe / 8; - size_t number_of_bytes = number_of_elements * bytes_per_element; - size_t block_size = 1024*1024; /* Use 1 MB blocks. Make sure that block size is smaller than 2^31 */ - size_t number_of_blocks = number_of_bytes / block_size; - size_t remaining_bytes = number_of_bytes % block_size; - size_t bytes_written = 0; - size_t block_nr = 0; - mitkIpUInt1_t* data = (mitkIpUInt1_t*) pic->data; - - assert( data != NULL ); - - if( pic->type == mitkIpPicNonUniform ) - { - for ( block_nr = 0 ; block_nr < number_of_blocks ; ++block_nr ) - bytes_written += mitkIpPicFWrite( data + ( block_nr * block_size ), 1, block_size, outfile ); - bytes_written += mitkIpPicFWrite( data + ( number_of_blocks * block_size ), 1, remaining_bytes, outfile ); - } - else - { - for ( block_nr = 0 ; block_nr < number_of_blocks ; ++block_nr ) - bytes_written += mitkIpPicFWriteLE( data + ( block_nr * block_size ), 1, block_size, outfile ); - bytes_written += mitkIpPicFWriteLE( data + ( number_of_blocks * block_size ), 1, remaining_bytes, outfile ); - } - - if ( bytes_written != number_of_bytes ) - { - fprintf( stderr, "Error while writing (ferror indicates %u), only %u bytes were written! Eof indicator is %u.\n", ferror(outfile), ( (unsigned int) ( bytes_written ) ), feof(outfile) ); - fclose( outfile ); - return( -1 ); - } - } - - if( outfile != stdout ) - { - // Removed due to linker problems when compiling - // an mitk chili plugin using msvc: there appear - // unresolved external symbol errors to function - // _ipPicGetWriteCompression() - /* - if( mitkIpPicGetWriteCompression() ) - mitkIpPicFClose( outfile ); - else - */ - fclose( outfile ); - } - - return( 0 ); -} - -std::vector mitk::PicFileWriter::GetPossibleFileExtensions() -{ - std::vector possibleFileExtensions; - possibleFileExtensions.push_back(".pic"); - return possibleFileExtensions; -} - -std::string mitk::PicFileWriter::GetSupportedBaseData() const -{ - return Image::GetStaticNameOfClass(); -} diff --git a/Modules/IpPicSupport/mitkPicFileWriter.h b/Modules/IpPicSupport/mitkPicFileWriter.h deleted file mode 100644 index 3b4f4252ff..0000000000 --- a/Modules/IpPicSupport/mitkPicFileWriter.h +++ /dev/null @@ -1,122 +0,0 @@ -/*=================================================================== - -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 _MITK_PIC_FILE_WRITER__H_ -#define _MITK_PIC_FILE_WRITER__H_ - -#include -#include -#include - -#include "mitkLegacyAdaptors.h" - - -namespace mitk -{ -class Image; -/** - * @brief Writer for mitk::Image - * @ingroup IO - */ -class MitkIpPicSupport_EXPORT PicFileWriter : public mitk::FileWriter -{ -public: - - mitkClassMacro( PicFileWriter, mitk::FileWriter ); - - itkFactorylessNewMacro(Self) - itkCloneMacro(Self) - - mitkWriterMacro; - - /** - * Sets the filename of the file to write. - * @param _arg the name of the file to write. - */ - itkSetStringMacro( FileName ); - - /** - * @returns the name of the file to be written to disk. - */ - itkGetStringMacro( FileName ); - - /** - * @warning multiple write not (yet) supported - */ - itkSetStringMacro( FilePrefix ); - - /** - * @warning multiple write not (yet) supported - */ - itkGetStringMacro( FilePrefix ); - - /** - * @warning multiple write not (yet) supported - */ - itkSetStringMacro( FilePattern ); - - /** - * @warning multiple write not (yet) supported - */ - itkGetStringMacro( FilePattern ); - - /** - * Sets the 0'th input object for the filter. - * @param input the first input for the filter. - */ - void SetInputImage( mitk::Image* input ); - - /** - * @returns the 0'th input object of the filter. - */ - const mitk::Image* GetInput(); - - - /** - * @return possible file extensions for the data type associated with the writer - */ - virtual std::vector GetPossibleFileExtensions(); - - std::string GetSupportedBaseData() const; - - -protected: - - /** - * Constructor. - */ - PicFileWriter(); - - /** - * Virtual destructor. - */ - virtual ~PicFileWriter(); - - virtual void GenerateData(); - - virtual int MITKIpPicPut( char *outfile_name, mitkIpPicDescriptor *pic ); - - std::string m_FileName; - - std::string m_FilePrefix; - - std::string m_FilePattern; -}; - -} - -#endif //_MITK_PIC_FILE_WRITER__H_ diff --git a/Modules/IpPicSupport/mitkPicHelper.cpp b/Modules/IpPicSupport/mitkPicHelper.cpp deleted file mode 100644 index 04a27fb3f8..0000000000 --- a/Modules/IpPicSupport/mitkPicHelper.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/*=================================================================== - -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 "mitkConfig.h" -#include "mitkPicHelper.h" -#include "mitkSlicedGeometry3D.h" -#include "mitkPlaneGeometry.h" -#ifdef HAVE_IPDICOM -#include "ipDicom/ipDicom.h" -#endif /* HAVE_IPDICOM */ - -bool mitk::PicHelper::GetSpacing(const mitkIpPicDescriptor* aPic, Vector3D & spacing) -{ - mitkIpPicDescriptor* pic = const_cast(aPic); - - mitkIpPicTSV_t *tsv; - bool pixelSize = false; - - tsv = mitkIpPicQueryTag( pic, "REAL PIXEL SIZE" ); - if(tsv==NULL) - { - tsv = mitkIpPicQueryTag( pic, "PIXEL SIZE" ); - pixelSize = true; - } - if(tsv) - { - bool tagFound = false; - if((tsv->dim*tsv->n[0]>=3) && (tsv->type==mitkIpPicFloat)) - { - if(tsv->bpe==32) - { - FillVector3D(spacing,((mitkIpFloat4_t*)tsv->value)[0], ((mitkIpFloat4_t*)tsv->value)[1],((mitkIpFloat4_t*)tsv->value)[2]); - tagFound = true; - } - else - if(tsv->bpe==64) - { - FillVector3D(spacing,((mitkIpFloat8_t*)tsv->value)[0], ((mitkIpFloat8_t*)tsv->value)[1],((mitkIpFloat8_t*)tsv->value)[2]); - tagFound = true; - } - } - if(tagFound && pixelSize) - { - tsv = mitkIpPicQueryTag( pic, "PIXEL SPACING" ); - if(tsv) - { - mitk::ScalarType zSpacing = 0; - if((tsv->dim*tsv->n[0]>=3) && (tsv->type==mitkIpPicFloat)) - { - if(tsv->bpe==32) - { - zSpacing = ((mitkIpFloat4_t*)tsv->value)[2]; - } - else - if(tsv->bpe==64) - { - zSpacing = ((mitkIpFloat8_t*)tsv->value)[2]; - } - if(zSpacing != 0) - { - spacing[2] = zSpacing; - } - } - } - } - if(tagFound) return true; - } -#ifdef HAVE_IPDICOM - tsv = mitkIpPicQueryTag( pic, "SOURCE HEADER" ); - if( tsv ) - { - void *data; - mitkIpUInt4_t len; - mitkIpFloat8_t spacing_z = 0; - mitkIpFloat8_t thickness = 1; - mitkIpFloat8_t fx = 1; - mitkIpFloat8_t fy = 1; - bool ok=false; - - if( dicomFindElement( (unsigned char *) tsv->value, 0x0018, 0x0088, &data, &len ) ) - { - ok=true; - sscanf( (char *) data, "%lf", &spacing_z ); -// itkGenericOutputMacro( "spacing: " << spacing_z << " mm"); - } - if( dicomFindElement( (unsigned char *) tsv->value, 0x0018, 0x0050, &data, &len ) ) - { - ok=true; - sscanf( (char *) data, "%lf", &thickness ); -// itkGenericOutputMacro( "thickness: " << thickness << " mm"); - - if( thickness == 0 ) - thickness = 1; - } - if( dicomFindElement( (unsigned char *) tsv->value, 0x0028, 0x0030, &data, &len ) - && len>0 && ((char *)data)[0] ) - { - sscanf( (char *) data, "%lf\\%lf", &fy, &fx ); // row / column value -// itkGenericOutputMacro( "fx, fy: " << fx << "/" << fy << " mm"); - } - else - ok=false; - if(ok) - FillVector3D(spacing, fx, fy,( spacing_z > 0 ? spacing_z : thickness)); - return ok; - } -#endif /* HAVE_IPDICOM */ - if(spacing[0]<=0 || spacing[1]<=0 || spacing[2]<=0) - { - itkGenericOutputMacro(<< "illegal spacing by pic tag: " << spacing << ". Setting spacing to (1,1,1)."); - spacing.Fill(1); - } - return false; -} - -bool mitk::PicHelper::GetTimeSpacing(const mitkIpPicDescriptor* aPic, float& timeSpacing) -{ - mitkIpPicDescriptor* pic = const_cast(aPic); - - mitkIpPicTSV_t *tsv; - - tsv = mitkIpPicQueryTag( pic, "PIXEL SIZE" ); - if(tsv) - { - timeSpacing = ((mitkIpFloat4_t*)tsv->value)[3]; - if( timeSpacing <=0 ) timeSpacing = 1; - } - else timeSpacing = 1; - return true; -} - -bool mitk::PicHelper::SetSpacing(const mitkIpPicDescriptor* aPic, SlicedGeometry3D* slicedgeometry) -{ - mitkIpPicDescriptor* pic = const_cast(aPic); - - Vector3D spacing(slicedgeometry->GetSpacing()); - - mitkIpPicTSV_t *tsv; - if ( (tsv = mitkIpPicQueryTag( pic, "REAL PIXEL SIZES" )) != NULL) - { - int count = tsv->n[1]; - float* value = (float*) tsv->value; - mitk::Vector3D pixelSize; - spacing.Fill(0); - - for ( int s=0; s < count; s++ ) - { - pixelSize[0] = (ScalarType) *value++; - pixelSize[1] = (ScalarType) *value++; - pixelSize[2] = (ScalarType) *value++; - spacing += pixelSize; - } - spacing *= 1.0f/count; - slicedgeometry->SetSpacing(spacing); - - itkGenericOutputMacro(<< "the slices are inhomogeneous" ); - } - else - if(GetSpacing(pic, spacing)) - { - slicedgeometry->SetSpacing(spacing); - return true; - } - return false; -} - -void mitk::PicHelper::InitializeEvenlySpaced(const mitkIpPicDescriptor* pic, unsigned int slices, SlicedGeometry3D* slicedgeometry) -{ - assert(pic!=NULL); - assert(slicedgeometry!=NULL); - - mitk::PlaneGeometry::Pointer planegeometry=mitk::PlaneGeometry::New(); - - mitkIpPicTSV_t *geometryTag; - if ( (geometryTag = mitkIpPicQueryTag( const_cast(pic), "ISG" )) != NULL) - { - mitk::Point3D origin; - mitk::Vector3D rightVector; - mitk::Vector3D downVector; - mitk::Vector3D spacing; - - mitk::vtk2itk(((float*)geometryTag->value+0), origin); - mitk::vtk2itk(((float*)geometryTag->value+3), rightVector); - mitk::vtk2itk(((float*)geometryTag->value+6), downVector); - mitk::vtk2itk(((float*)geometryTag->value+9), spacing); - - mitk::PlaneGeometry::Pointer planegeometry = PlaneGeometry::New(); - planegeometry->InitializeStandardPlane(pic->n[0], pic->n[1], rightVector, downVector, &spacing); - planegeometry->SetOrigin(origin); - slicedgeometry->InitializeEvenlySpaced(planegeometry, slices); - } - else - { - Vector3D spacing; - spacing.Fill(1); - GetSpacing(pic, spacing); - planegeometry->InitializeStandardPlane(pic->n[0], pic->n[1], spacing); - slicedgeometry->InitializeEvenlySpaced(planegeometry, spacing[2], slices); - } -} - -bool mitk::PicHelper::SetPlaneGeometry(const mitkIpPicDescriptor* aPic, int s, SlicedGeometry3D* slicedgeometry) -{ - mitkIpPicDescriptor* pic = const_cast(aPic); - if((pic!=NULL) && (slicedgeometry->IsValidSlice(s))) - { - //construct standard view - mitk::Point3D origin; - mitk::Vector3D rightDV, bottomDV; - mitkIpPicTSV_t *tsv; - if ( (tsv = mitkIpPicQueryTag( pic, "REAL PIXEL SIZES" )) != NULL) - { - unsigned int count = (unsigned int) tsv->n[1]; - float* value = (float*) tsv->value; - mitk::Vector3D pixelSize; - ScalarType zPosition = 0.0f; - - if(s >= 0) - { - if(count < (unsigned int) s) - return false; - count = s; - } - else - { - if(count < slicedgeometry->GetSlices()) - return false; - count = slicedgeometry->GetSlices(); - } - - unsigned int slice; - for (slice=0; slice < count; ++slice ) - { - pixelSize[0] = (ScalarType) *value++; - pixelSize[1] = (ScalarType) *value++; - pixelSize[2] = (ScalarType) *value++; - - zPosition += pixelSize[2] / 2.0f; // first half slice thickness - - if((s==-1) || (slice== (unsigned int) s)) - { - Vector3D spacing; - spacing = pixelSize; - FillVector3D(origin, 0, 0, zPosition); - FillVector3D(rightDV, pic->n[0], 0, 0); - FillVector3D(bottomDV, 0, pic->n[1], 0); - - mitk::PlaneGeometry::Pointer planegeometry=mitk::PlaneGeometry::New(); - planegeometry->InitializeStandardPlane(pic->n[0], pic->n[1], rightDV.GetVnlVector(), bottomDV.GetVnlVector(), &spacing); - planegeometry->SetOrigin(origin); - slicedgeometry->SetPlaneGeometry(planegeometry, s); - } - - zPosition += pixelSize[2] / 2.0f; // second half slice thickness - } - } - else - { - FillVector3D(origin,0,0,s); slicedgeometry->IndexToWorld(origin, origin); - FillVector3D(rightDV,pic->n[0],0,0); - FillVector3D(bottomDV,0,pic->n[1],0); - - mitk::PlaneGeometry::Pointer planegeometry=mitk::PlaneGeometry::New(); - planegeometry->InitializeStandardPlane(pic->n[0], pic->n[1], rightDV.GetVnlVector(), bottomDV.GetVnlVector(), &slicedgeometry->GetSpacing()); - planegeometry->SetOrigin(origin); - slicedgeometry->SetPlaneGeometry(planegeometry, s); - } - return true; - } - return false; -} diff --git a/Modules/IpPicSupport/mitkPicHelper.h b/Modules/IpPicSupport/mitkPicHelper.h deleted file mode 100644 index b30a00f3bb..0000000000 --- a/Modules/IpPicSupport/mitkPicHelper.h +++ /dev/null @@ -1,58 +0,0 @@ -/*=================================================================== - -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 MITKPICHELPER_H_HEADER_INCLUDED_C1F4DAB4 -#define MITKPICHELPER_H_HEADER_INCLUDED_C1F4DAB4 - -#include -#include "mitkNumericTypes.h" -#include -#include - -namespace mitk { - -class SlicedGeometry3D; - -//##Documentation -//## @brief Internal class for managing references on sub-images -//## @ingroup Data -class MitkIpPicSupport_EXPORT PicHelper -{ -public: - static const char *GetNameOfClass() { return "PicHelper"; } - - static bool GetSpacing(const mitkIpPicDescriptor* pic, Vector3D & spacing); - - static bool SetSpacing(const mitkIpPicDescriptor* pic, SlicedGeometry3D* slicedgeometry); - - static bool GetTimeSpacing(const mitkIpPicDescriptor* pic, float& timeSpacing); - - static void InitializeEvenlySpaced(const mitkIpPicDescriptor* pic, unsigned int slices, SlicedGeometry3D* slicedgeometry); - - static bool SetPlaneGeometry(const mitkIpPicDescriptor* pic, int s, SlicedGeometry3D* slicedgeometry); - - /** - * \deprecatedSince{2014_06} Please use SetPlaneGeometry - */ - DEPRECATED(static bool SetGeometry2D(const mitkIpPicDescriptor* pic, int s, SlicedGeometry3D* slicedgeometry)){return SetPlaneGeometry(pic,s,slicedgeometry);}; -}; - -} // namespace mitk - - - -#endif /* MITKPICHELPER_H_HEADER_INCLUDED_C1F4DAB4 */ diff --git a/Modules/IpPicSupport/mitkPicVolumeTimeSeriesIOFactory.cpp b/Modules/IpPicSupport/mitkPicVolumeTimeSeriesIOFactory.cpp deleted file mode 100644 index 061b94e7f9..0000000000 --- a/Modules/IpPicSupport/mitkPicVolumeTimeSeriesIOFactory.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/*=================================================================== - -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 "mitkPicVolumeTimeSeriesIOFactory.h" -#include "mitkIOAdapter.h" -#include "mitkPicVolumeTimeSeriesReader.h" - -#include "itkVersion.h" - - -namespace mitk -{ -PicVolumeTimeSeriesIOFactory::PicVolumeTimeSeriesIOFactory() -{ - this->RegisterOverride("mitkIOAdapter", - "mitkPicVolumeTimeSeriesReader", - "mitk Pic Image IO", - 1, - itk::CreateObjectFunction >::New()); -} - -PicVolumeTimeSeriesIOFactory::~PicVolumeTimeSeriesIOFactory() -{ -} - -const char* PicVolumeTimeSeriesIOFactory::GetITKSourceVersion() const -{ - return ITK_SOURCE_VERSION; -} - -const char* PicVolumeTimeSeriesIOFactory::GetDescription() const -{ - return "PicVolumeTimeSeries IO Factory, allows the loading of DKFZ Pic images"; -} - -} // end namespace mitk diff --git a/Modules/IpPicSupport/mitkPicVolumeTimeSeriesIOFactory.h b/Modules/IpPicSupport/mitkPicVolumeTimeSeriesIOFactory.h deleted file mode 100644 index 6fb82bd8fe..0000000000 --- a/Modules/IpPicSupport/mitkPicVolumeTimeSeriesIOFactory.h +++ /dev/null @@ -1,73 +0,0 @@ -/*=================================================================== - -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 __mitkPicVolumeTimeSeriesIOFactory_h -#define __mitkPicVolumeTimeSeriesIOFactory_h - -#ifdef _MSC_VER -#pragma warning ( disable : 4786 ) -#endif - -#include - -#include "itkObjectFactoryBase.h" -#include "mitkBaseData.h" - -namespace mitk -{ -//##Documentation -//## @brief Create instances of PicVolumeTimeSeriesReader objects using an object factory. -//## -//## @ingroup IO -class MitkIpPicSupport_EXPORT PicVolumeTimeSeriesIOFactory : public itk::ObjectFactoryBase -{ -public: - /** Standard class typedefs. */ - typedef PicVolumeTimeSeriesIOFactory Self; - typedef itk::ObjectFactoryBase Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; - - /** Class methods used to interface with the registered factories. */ - virtual const char* GetITKSourceVersion(void) const; - virtual const char* GetDescription(void) const; - - /** Method for class instantiation. */ - itkFactorylessNewMacro(Self); - static PicVolumeTimeSeriesIOFactory* FactoryNew() { return new PicVolumeTimeSeriesIOFactory;} - /** Run-time type information (and related methods). */ - itkTypeMacro(PicVolumeTimeSeriesIOFactory, ObjectFactoryBase); - - /** Register one factory of this type */ - static void RegisterOneFactory(void) - { - PicVolumeTimeSeriesIOFactory::Pointer PicVolumeTimeSeriesIOFactory = PicVolumeTimeSeriesIOFactory::New(); - ObjectFactoryBase::RegisterFactory(PicVolumeTimeSeriesIOFactory); - } - -protected: - PicVolumeTimeSeriesIOFactory(); - ~PicVolumeTimeSeriesIOFactory(); - -private: - PicVolumeTimeSeriesIOFactory(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented - -}; - - -} // end namespace mitk - -#endif diff --git a/Modules/IpPicSupport/mitkPicVolumeTimeSeriesReader.cpp b/Modules/IpPicSupport/mitkPicVolumeTimeSeriesReader.cpp deleted file mode 100644 index c8bf0892ce..0000000000 --- a/Modules/IpPicSupport/mitkPicVolumeTimeSeriesReader.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/*=================================================================== - -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 "mitkPicVolumeTimeSeriesReader.h" -#include "mitkPicFileReader.h" -#include -#include - -extern "C" -{ -mitkIpPicDescriptor * MITKipPicGet( char *infile_name, mitkIpPicDescriptor *pic ); -mitkIpPicDescriptor * MITKipPicGetTags( char *infile_name, mitkIpPicDescriptor *pic ); -} - - -void mitk::PicVolumeTimeSeriesReader::GenerateOutputInformation() -{ - mitk::Image::Pointer output = this->GetOutput(); - - if ( ( output->IsInitialized() ) && ( this->GetMTime() <= m_ReadHeaderTime.GetMTime() ) ) - return ; - - itkDebugMacro( << "Reading file for GenerateOutputInformation()" << m_FileName ); - - if ( ! this->GenerateFileList() ) - { - itkWarningMacro( "Sorry, file list could not be generated!" ); - return ; - } - - // - // Read the first file of the image sequence. Assume equal size and spacings for all - // other volumes. @TODO Integrate support for different sizes and spacings - // - char* filename = const_cast ( m_MatchedFileNames[ 0 ].c_str() ); - mitkIpPicDescriptor * header = mitkIpPicGetHeader( filename, NULL ); - header = MITKipPicGetTags( filename, header ); - - if ( header == NULL ) - { - itk::ImageFileReaderException e( __FILE__, __LINE__ ); - std::ostringstream msg; - msg << " Could not read file " << m_FileName.c_str(); - e.SetDescription( msg.str().c_str() ); - throw e; - return ; - } - if ( header->dim != 3 ) - { - itk::ImageFileReaderException e( __FILE__, __LINE__ , "Only 3D-pic volumes are supported! " ); - throw e; - return ; - } - - // - // modify the header to match the real temporal extent - // - header->dim = 4; - header->n[ 3 ] = m_MatchedFileNames.size(); - - output->Initialize( CastToImageDescriptor( header) ); - - mitkIpPicFree( header ); - - m_ReadHeaderTime.Modified(); -} - - -void mitk::PicVolumeTimeSeriesReader::GenerateData() -{ - mitk::Image::Pointer output = this->GetOutput(); - - // - // Check to see if we can read the file given the name or prefix - // - if ( m_FilePrefix == "" || m_FilePattern == "" ) - { - throw itk::ImageFileReaderException( __FILE__, __LINE__, "Both FilePattern and FilePrefix must be non-empty" ); - } - - if ( m_MatchedFileNames.size() == 0 ) - { - throw itk::ImageFileReaderException( __FILE__, __LINE__, "Sorry, there are no files to read!" ); - } - - - // - // read 3d volumes and copy them to the 4d volume - // - mitkIpPicDescriptor* volume3d = NULL; - for ( unsigned int t = 0 ; t < m_MatchedFileNames.size() ; ++t ) - { - char* filename = const_cast< char* >( m_MatchedFileNames[ t ].c_str() ); - MITK_INFO << "Reading file " << filename << "..." << std::endl; - volume3d = MITKipPicGet( filename, NULL ); - - if ( volume3d == NULL ) - { - std::ostringstream message; - message << "mitk::ERROR: " << this->GetNameOfClass() << "(" << this << "): " - << "File (" << filename << ") of time frame " << t << " could not be read!"; - throw itk::ImageFileReaderException( __FILE__, __LINE__, message.str().c_str() ); - } - - // - // @TODO do some error checking - // - - // - // copy the 3d data volume to the 4d volume - // - - // \todo use memory of Image as in PicFileReader (or integrate everything into the PicFileReader!) - PicFileReader::ConvertHandedness(volume3d); - bool result = false; - // FIXME - //result = output->SetPicVolume( volume3d, t ); - if(result==false) - { - std::ostringstream message; - message << "mitk::ERROR: " << this->GetNameOfClass() << "(" << this << "): " - << "Volume of time frame " << t << " did not match size of other time frames."; - throw itk::ImageFileReaderException( __FILE__, __LINE__, message.str().c_str() ); - } - mitkIpPicFree ( volume3d ); - } -} - -bool mitk::PicVolumeTimeSeriesReader::CanReadFile(const std::string /*filename*/, const std::string filePrefix, const std::string filePattern) -{ - if( filePattern == "" && filePrefix == "" ) - return false; - - bool extensionFound = false; - std::string::size_type PICPos = filePattern.rfind(".pic"); - if ((PICPos != std::string::npos) - && (PICPos == filePattern.length() - 4)) - { - extensionFound = true; - } - - PICPos = filePattern.rfind(".pic.gz"); - if ((PICPos != std::string::npos) - && (PICPos == filePattern.length() - 7)) - { - extensionFound = true; - } - - if( !extensionFound ) - return false; - - return true; -} - -mitk::PicVolumeTimeSeriesReader::PicVolumeTimeSeriesReader() -{ - //this->DebugOn(); -} - -mitk::PicVolumeTimeSeriesReader::~PicVolumeTimeSeriesReader() -{} - diff --git a/Modules/IpPicSupport/mitkPicVolumeTimeSeriesReader.h b/Modules/IpPicSupport/mitkPicVolumeTimeSeriesReader.h deleted file mode 100644 index c6e60f26ce..0000000000 --- a/Modules/IpPicSupport/mitkPicVolumeTimeSeriesReader.h +++ /dev/null @@ -1,70 +0,0 @@ -/*=================================================================== - -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 _PIC_VOLUME_TIME_SERIES_READER__H_ -#define _PIC_VOLUME_TIME_SERIES_READER__H_ - -#include -#include "mitkFileSeriesReader.h" -#include "mitkImageSource.h" -#include - -namespace mitk -{ -//##Documentation -//## @brief Reader to read a series of volume files in DKFZ-pic-format -//## @ingroup IO -class MitkIpPicSupport_EXPORT PicVolumeTimeSeriesReader : public ImageSource, public FileSeriesReader -{ -public: - mitkClassMacro( PicVolumeTimeSeriesReader, FileReader ); - - /** Method for creation through the object factory. */ - itkFactorylessNewMacro(Self) - itkCloneMacro(Self) - - itkSetStringMacro(FileName); - itkGetStringMacro(FileName); - - itkSetStringMacro(FilePrefix); - itkGetStringMacro(FilePrefix); - - itkSetStringMacro(FilePattern); - itkGetStringMacro(FilePattern); - - static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern); - -protected: - virtual void GenerateData(); - - virtual void GenerateOutputInformation(); - - PicVolumeTimeSeriesReader(); - - ~PicVolumeTimeSeriesReader(); - - //##Description - //## @brief Time when Header was last read - itk::TimeStamp m_ReadHeaderTime; - -}; - -} // namespace mitk - -#endif - - diff --git a/Modules/IpPicSupportIO/Internal/mitkIpPicSupportIOActivator.cpp b/Modules/IpPicSupportIO/Internal/mitkIpPicSupportIOActivator.cpp new file mode 100644 index 0000000000..f21ca7fa7a --- /dev/null +++ b/Modules/IpPicSupportIO/Internal/mitkIpPicSupportIOActivator.cpp @@ -0,0 +1,40 @@ +/*=================================================================== + +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 "mitkPicFileReader.h" + +class US_ABI_LOCAL mitkIpPicSupportIOActivator : public us::ModuleActivator +{ +public: + + void Load(us::ModuleContext*) + { + m_Reader = new mitk::PicFileReader(); + } + + void Unload(us::ModuleContext* ) + { + delete m_Reader; + } + +private: + + mitk::IFileReader* m_Reader; +}; + +US_EXPORT_MODULE_ACTIVATOR(MitkIpPicSupportIO, mitkIpPicSupportIOActivator) diff --git a/Modules/IpPicSupportIO/Internal/mitkPicFileIOFactory.cpp b/Modules/IpPicSupportIO/Internal/mitkPicFileIOFactory.cpp deleted file mode 100644 index f9858b8f20..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkPicFileIOFactory.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/*=================================================================== - -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 "mitkPicFileIOFactory.h" -#include "mitkIOAdapter.h" -#include "mitkPicFileReader.h" -#include "mitkCoreObjectFactory.h" - -#include "itkVersion.h" - - -namespace mitk -{ -PicFileIOFactory::PicFileIOFactory() -{ - this->RegisterOverride("mitkIOAdapter", - "mitkPicFileReader", - "mitk Pic Image IO", - 1, - itk::CreateObjectFunction >::New()); -} - -PicFileIOFactory::~PicFileIOFactory() -{ -} - -const char* PicFileIOFactory::GetITKSourceVersion() const -{ - return ITK_SOURCE_VERSION; -} - -const char* PicFileIOFactory::GetDescription() const -{ - return "PicFile IO Factory, allows the loading of DKFZ Pic images"; -} - -} // end namespace mitk - -struct RegisterIpPicIOFactory{ - RegisterIpPicIOFactory() - : m_Factory( mitk::PicFileIOFactory::New() ) - { - MITK_DEBUG << "Registering PicFileIOFactory "; - itk::ObjectFactoryBase::RegisterFactory( m_Factory ); - } - - ~RegisterIpPicIOFactory() - { - itk::ObjectFactoryBase::UnRegisterFactory( m_Factory ); - } - - mitk::PicFileIOFactory::Pointer m_Factory; -}; - -static RegisterIpPicIOFactory registerIpPicIOFactory; diff --git a/Modules/IpPicSupportIO/Internal/mitkPicFileIOFactory.h b/Modules/IpPicSupportIO/Internal/mitkPicFileIOFactory.h deleted file mode 100644 index 521fdfbfd6..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkPicFileIOFactory.h +++ /dev/null @@ -1,71 +0,0 @@ -/*=================================================================== - -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 __mitkPicFileIOFactory_h -#define __mitkPicFileIOFactory_h - -#ifdef _MSC_VER -#pragma warning ( disable : 4786 ) -#endif - -#include "itkObjectFactoryBase.h" -#include "mitkBaseData.h" - -namespace mitk -{ -//##Documentation -//## @brief Create instances of PicFileReader objects using an object factory. -class PicFileIOFactory : public itk::ObjectFactoryBase -{ -public: - /** Standard class typedefs. */ - typedef PicFileIOFactory Self; - typedef itk::ObjectFactoryBase Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; - - /** Class methods used to interface with the registered factories. */ - virtual const char* GetITKSourceVersion(void) const; - virtual const char* GetDescription(void) const; - - /** Method for class instantiation. */ - itkFactorylessNewMacro(Self); - static PicFileIOFactory* FactoryNew() { return new PicFileIOFactory;} - /** Run-time type information (and related methods). */ - itkTypeMacro(PicFileIOFactory, ObjectFactoryBase); - - /** Register one factory of this type */ -/* static void RegisterOneFactory(void) - { - std::cout << "Register PicFile Factory."; - - PicFileIOFactory::Pointer PicFileIOFactory = PicFileIOFactory::New(); - ObjectFactoryBase::RegisterFactory(PicFileIOFactory); - } -*/ -protected: - PicFileIOFactory(); - ~PicFileIOFactory(); - -private: - PicFileIOFactory(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented - -}; - - -} // end namespace mitk - -#endif diff --git a/Modules/IpPicSupportIO/Internal/mitkPicFileReader.cpp b/Modules/IpPicSupportIO/Internal/mitkPicFileReader.cpp index 6d7ef8b786..ce79f65eb0 100644 --- a/Modules/IpPicSupportIO/Internal/mitkPicFileReader.cpp +++ b/Modules/IpPicSupportIO/Internal/mitkPicFileReader.cpp @@ -1,376 +1,205 @@ /*=================================================================== 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 "mitkPicFileReader.h" #include "mitkPicHelper.h" -#include +#include "mitkLegacyAdaptors.h" + #include "mitkImageWriteAccessor.h" -#include +#include "mitkCustomMimeType.h" extern "C" { mitkIpPicDescriptor * MITKipPicGet( char *infile_name, mitkIpPicDescriptor *pic ); mitkIpPicDescriptor * MITKipPicGetTags( char *infile_name, mitkIpPicDescriptor *pic ); } -void mitk::PicFileReader::GenerateOutputInformation() +mitk::PicFileReader::PicFileReader() + : AbstractFileReader() { - Image::Pointer output = this->GetOutput(); + CustomMimeType mimeType(this->GetMimeTypePrefix() + "mbipic"); + mimeType.AddExtension("pic"); + mimeType.AddExtension("pic.gz"); + mimeType.AddExtension("PIC"); + mimeType.AddExtension("PIC.gz"); + mimeType.SetCategory("Images"); + mimeType.SetComment("DKFZ Legacy PIC Format"); + + this->SetMimeType(mimeType); + this->SetDescription("DKFZ PIC"); + + this->RegisterService(); +} - if ((output->IsInitialized()) && (this->GetMTime() <= m_ReadHeaderTime.GetMTime())) - return; +std::vector mitk::PicFileReader::Read() +{ + mitk::Image::Pointer image = this->CreateImage(); + this->FillImage(image); + std::vector result; + result.push_back(image.GetPointer()); + return result; +} - itkDebugMacro(<<"Reading file for GenerateOutputInformation()" << m_FileName); +mitk::Image::Pointer mitk::PicFileReader::CreateImage() +{ + Image::Pointer output = Image::New(); - // Check to see if we can read the file given the name or prefix - // - if ( m_FileName == "" && m_FilePrefix == "" ) - { - throw itk::ImageFileReaderException(__FILE__, __LINE__, "One of FileName or FilePrefix must be non-empty"); - } + std::string fileName = this->GetLocalFileName(); - if( m_FileName != "") - { - mitkIpPicDescriptor* header=mitkIpPicGetHeader(const_cast(m_FileName.c_str()), NULL); - - if ( !header ) - { - throw itk::ImageFileReaderException(__FILE__, __LINE__, "File could not be read."); - } - - header=MITKipPicGetTags(const_cast(m_FileName.c_str()), header); - - int channels = 1; - - mitkIpPicTSV_t *tsv; - if ( (tsv = mitkIpPicQueryTag( header, "SOURCE HEADER" )) != NULL) - { - if(tsv->n[0]>1e+06) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag( header, "SOURCE HEADER" ); - mitkIpPicFreeTag(tsvSH); - } - } - if ( (tsv = mitkIpPicQueryTag( header, "ICON80x80" )) != NULL) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag( header, "ICON80x80" ); - mitkIpPicFreeTag(tsvSH); - } - if ( (tsv = mitkIpPicQueryTag( header, "VELOCITY" )) != NULL) - { - ++channels; - mitkIpPicDelTag( header, "VELOCITY" ); - } - - if( header == NULL || header->bpe == 0) - { - itk::ImageFileReaderException e(__FILE__, __LINE__); - std::ostringstream msg; - msg << " Could not read file " - << m_FileName.c_str(); - e.SetDescription(msg.str().c_str()); - throw e; - return; - } - - // if pic image only 2D, the n[2] value is not initialized - unsigned int slices = 1; - if( header->dim == 2 ) - header->n[2] = slices; - - // First initialize the geometry of the output image by the pic-header - SlicedGeometry3D::Pointer slicedGeometry = mitk::SlicedGeometry3D::New(); - PicHelper::InitializeEvenlySpaced(header, header->n[2], slicedGeometry); - - // if pic image only 3D, the n[3] value is not initialized - unsigned int timesteps = 1; - if( header->dim > 3 ) - timesteps = header->n[3]; - - slicedGeometry->ImageGeometryOn(); - ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); - timeGeometry->Initialize(slicedGeometry, timesteps); - - // Cast the pic descriptor to ImageDescriptor and initialize the output - - output->Initialize( CastToImageDescriptor(header)); - output->SetTimeGeometry( timeGeometry ); - mitkIpPicFree ( header ); - } - else + mitkIpPicDescriptor* header=mitkIpPicGetHeader(const_cast(fileName.c_str()), NULL); + + if ( !header ) + { + mitkThrow() << "File could not be read."; + } + + header=MITKipPicGetTags(const_cast(fileName.c_str()), header); + + int channels = 1; + + mitkIpPicTSV_t *tsv; + if ( (tsv = mitkIpPicQueryTag( header, "SOURCE HEADER" )) != NULL) + { + if(tsv->n[0]>1e+06) { - int numberOfImages=0; - m_StartFileIndex=0; - - mitkIpPicDescriptor* header=NULL; - - char fullName[1024]; - - while(m_StartFileIndex<10) - { - sprintf(fullName, m_FilePattern.c_str(), m_FilePrefix.c_str(), m_StartFileIndex+numberOfImages); - FILE * f=fopen(fullName,"r"); - if(f==NULL) - { - //already found an image? - if(numberOfImages>0) - break; - //no? let's increase start - ++m_StartFileIndex; - } - else - { - fclose(f); - //only open the header of the first file found, - //@warning what to do when images do not have the same size?? - if(header==NULL) - { - header=mitkIpPicGetHeader(fullName, NULL); - header=MITKipPicGetTags(fullName, header); - } - ++numberOfImages; - } - } - - printf("\n numberofimages %d\n",numberOfImages); - - if(numberOfImages==0) - { - itk::ImageFileReaderException e(__FILE__, __LINE__); - std::ostringstream msg; - msg << "no images found"; - e.SetDescription(msg.str().c_str()); - throw e; - return; - } - - //@FIXME: was ist, wenn die Bilder nicht alle gleich gross sind? - if(numberOfImages>1) - { - printf("\n numberofimages %d > 1\n",numberOfImages); - header->dim=3; - header->n[2]=numberOfImages; - } - - printf(" \ninitialisize output\n"); - output->Initialize( CastToImageDescriptor(header) ); - mitkIpPicFree ( header ); + mitkIpPicTSV_t *tsvSH; + tsvSH = mitkIpPicDelTag( header, "SOURCE HEADER" ); + mitkIpPicFreeTag(tsvSH); } + } + if ( (tsv = mitkIpPicQueryTag( header, "ICON80x80" )) != NULL) + { + mitkIpPicTSV_t *tsvSH; + tsvSH = mitkIpPicDelTag( header, "ICON80x80" ); + mitkIpPicFreeTag(tsvSH); + } + if ( (tsv = mitkIpPicQueryTag( header, "VELOCITY" )) != NULL) + { + ++channels; + mitkIpPicDelTag( header, "VELOCITY" ); + } - m_ReadHeaderTime.Modified(); -} + if( header == NULL || header->bpe == 0) + { + mitkThrow() << " Could not read file " << fileName; + } -void mitk::PicFileReader::ConvertHandedness(mitkIpPicDescriptor* pic) -{ - //left to right handed conversion - if(pic->dim>=3) + // if pic image only 2D, the n[2] value is not initialized + unsigned int slices = 1; + if( header->dim == 2 ) { - mitkIpPicDescriptor* slice=mitkIpPicCopyHeader(pic, NULL); - slice->dim=2; - size_t size=_mitkIpPicSize(slice); - slice->data=malloc(size); + header->n[2] = slices; + } - size_t v, volumes = (pic->dim>3? pic->n[3] : 1); - size_t volume_size = size*pic->n[2]; + // First initialize the geometry of the output image by the pic-header + SlicedGeometry3D::Pointer slicedGeometry = mitk::SlicedGeometry3D::New(); + PicHelper::InitializeEvenlySpaced(header, header->n[2], slicedGeometry); - for(v=0; vdata; - unsigned char *p_last=(unsigned char *)pic->data; - p_first+=v*volume_size; - p_last+=size*(pic->n[2]-1)+v*volume_size; - - size_t i, smid=pic->n[2]/2; - for(i=0; idata, p_last, size); - memcpy(p_last, p_first, size); - memcpy(p_first, slice->data, size); - } - } - mitkIpPicFree(slice); + // if pic image only 3D, the n[3] value is not initialized + unsigned int timesteps = 1; + if( header->dim > 3 ) + { + timesteps = header->n[3]; } -} -void mitk::PicFileReader::GenerateData() -{ - Image::Pointer output = this->GetOutput(); + slicedGeometry->ImageGeometryOn(); + ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); + timeGeometry->Initialize(slicedGeometry, timesteps); - // Check to see if we can read the file given the name or prefix - // - if ( m_FileName == "" && m_FilePrefix == "" ) - { - throw itk::ImageFileReaderException(__FILE__, __LINE__, "One of FileName or FilePrefix must be non-empty"); - } + // Cast the pic descriptor to ImageDescriptor and initialize the output - if( m_FileName != "") - { - mitkIpPicDescriptor* outputPic = mitkIpPicNew(); - mitk::ImageWriteAccessor imageAccess(output); - outputPic = CastToIpPicDescriptor(output, &imageAccess, outputPic); - mitkIpPicDescriptor* pic=MITKipPicGet(const_cast(m_FileName.c_str()), - outputPic); - // comes upside-down (in MITK coordinates) from PIC file - ConvertHandedness(pic); - - mitkIpPicTSV_t *tsv; - if ( (tsv = mitkIpPicQueryTag( pic, "SOURCE HEADER" )) != NULL) - { - if(tsv->n[0]>1e+06) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag( pic, "SOURCE HEADER" ); - mitkIpPicFreeTag(tsvSH); - } - } - if ( (tsv = mitkIpPicQueryTag( pic, "ICON80x80" )) != NULL) - { - mitkIpPicTSV_t *tsvSH; - tsvSH = mitkIpPicDelTag( pic, "ICON80x80" ); - mitkIpPicFreeTag(tsvSH); - } - if ( (tsv = mitkIpPicQueryTag( pic, "VELOCITY" )) != NULL) - { - mitkIpPicDescriptor* header = mitkIpPicCopyHeader(pic, NULL); - header->data = tsv->value; - ConvertHandedness(header); - output->SetChannel(header->data, 1); - header->data = NULL; - mitkIpPicFree(header); - mitkIpPicDelTag( pic, "VELOCITY" ); - } - - //slice-wise reading - //currently much too slow. - //else - //{ - // int sstart, smax; - // int tstart, tmax; - - // sstart=output->GetRequestedRegion().GetIndex(2); - // smax=sstart+output->GetRequestedRegion().GetSize(2); - - // tstart=output->GetRequestedRegion().GetIndex(3); - // tmax=tstart+output->GetRequestedRegion().GetSize(3); - - // int s,t; - // for(s=sstart; s(m_FileName.c_str()), NULL, t*smax+s+1); - // output->SetPicSlice(pic,s,t); - // } - // } - //} - } - else - { - int position; - mitkIpPicDescriptor* pic=NULL; - - int zDim=(output->GetDimension()>2?output->GetDimensions()[2]:1); - printf("\n zdim is %u \n",zDim); - - for (position = 0; position < zDim; ++position) - { - char fullName[1024]; - - sprintf(fullName, m_FilePattern.c_str(), m_FilePrefix.c_str(), m_StartFileIndex+position); - - pic=MITKipPicGet(fullName, pic); - if(pic==NULL) - { - itkDebugMacro("Pic file '" << fullName << "' does not exist."); - } - /* FIXME else - if(output->SetPicSlice(pic, position)==false) - { - itkDebugMacro("Image '" << fullName << "' could not be added to Image."); - }*/ - } - if(pic!=NULL) - mitkIpPicFree(pic); - } -} + output->Initialize( CastToImageDescriptor(header)); + output->SetTimeGeometry( timeGeometry ); + mitkIpPicFree ( header ); -void mitk::PicFileReader::EnlargeOutputRequestedRegion(itk::DataObject *output) -{ - output->SetRequestedRegionToLargestPossibleRegion(); + return output; } -bool mitk::PicFileReader::CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern) +void mitk::PicFileReader::ConvertHandedness(mitkIpPicDescriptor* pic) { - // First check the extension - if( filename == "" ) + //left to right handed conversion + if(pic->dim>=3) { - //MITK_INFO<<"No filename specified."<dim=2; + size_t size=_mitkIpPicSize(slice); + slice->data=malloc(size); - bool extensionFound = false; - std::string::size_type PICPos = filename.rfind(".pic"); - if ((PICPos != std::string::npos) - && (PICPos == filename.length() - 4)) - { - extensionFound = true; - } + size_t v, volumes = (pic->dim>3? pic->n[3] : 1); + size_t volume_size = size*pic->n[2]; - PICPos = filename.rfind(".PIC"); - if ((PICPos != std::string::npos) - && (PICPos == filename.length() - 4)) + for(v=0; vdata; + unsigned char *p_last=(unsigned char *)pic->data; + p_first+=v*volume_size; + p_last+=size*(pic->n[2]-1)+v*volume_size; - PICPos = filename.rfind(".seq"); - if ((PICPos != std::string::npos) - && (PICPos == filename.length() - 4)) - { - extensionFound = true; - } - - if( !extensionFound ) - { - //MITK_INFO<<"The filename extension is not recognized."<n[2]/2; + for(i=0; idata, p_last, size); + memcpy(p_last, p_first, size); + memcpy(p_first, slice->data, size); + } } - - return true; + mitkIpPicFree(slice); + } } -mitk::PicFileReader::PicFileReader() - : m_FileName(""), m_FilePrefix(""), m_FilePattern("") +mitk::PicFileReader* mitk::PicFileReader::Clone() const { + return new PicFileReader(*this); } -mitk::PicFileReader::~PicFileReader() +void mitk::PicFileReader::FillImage(Image::Pointer output) { + mitkIpPicDescriptor* outputPic = mitkIpPicNew(); + mitk::ImageWriteAccessor imageAccess(output); + outputPic = CastToIpPicDescriptor(output, &imageAccess, outputPic); + mitkIpPicDescriptor* pic=MITKipPicGet(const_cast(this->GetLocalFileName().c_str()), + outputPic); + // comes upside-down (in MITK coordinates) from PIC file + ConvertHandedness(pic); + + mitkIpPicTSV_t *tsv; + if ( (tsv = mitkIpPicQueryTag( pic, "SOURCE HEADER" )) != NULL) + { + if(tsv->n[0]>1e+06) + { + mitkIpPicTSV_t *tsvSH; + tsvSH = mitkIpPicDelTag( pic, "SOURCE HEADER" ); + mitkIpPicFreeTag(tsvSH); + } + } + if ( (tsv = mitkIpPicQueryTag( pic, "ICON80x80" )) != NULL) + { + mitkIpPicTSV_t *tsvSH; + tsvSH = mitkIpPicDelTag( pic, "ICON80x80" ); + mitkIpPicFreeTag(tsvSH); + } + if ( (tsv = mitkIpPicQueryTag( pic, "VELOCITY" )) != NULL) + { + mitkIpPicDescriptor* header = mitkIpPicCopyHeader(pic, NULL); + header->data = tsv->value; + ConvertHandedness(header); + output->SetChannel(header->data, 1); + header->data = NULL; + mitkIpPicFree(header); + mitkIpPicDelTag( pic, "VELOCITY" ); + } } diff --git a/Modules/IpPicSupportIO/Internal/mitkPicFileReader.h b/Modules/IpPicSupportIO/Internal/mitkPicFileReader.h index 47747584e7..af240e9771 100644 --- a/Modules/IpPicSupportIO/Internal/mitkPicFileReader.h +++ b/Modules/IpPicSupportIO/Internal/mitkPicFileReader.h @@ -1,79 +1,57 @@ /*=================================================================== 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 PICFILEREADER_H_HEADER_INCLUDED_C1F48A22 #define PICFILEREADER_H_HEADER_INCLUDED_C1F48A22 -#include "mitkFileReader.h" -#include "mitkImageSource.h" +#include "mitkAbstractFileReader.h" + +#include "mitkImage.h" #include "mitkIpPic.h" namespace mitk { //##Documentation //## @brief Reader to read files in DKFZ-pic-format -class PicFileReader : public ImageSource, public FileReader +class PicFileReader : public AbstractFileReader { -public: - mitkClassMacro(PicFileReader, FileReader); - - /** Method for creation through the object factory. */ - itkFactorylessNewMacro(Self) - itkCloneMacro(Self) - - itkSetStringMacro(FileName); - itkGetStringMacro(FileName); - - itkSetStringMacro(FilePrefix); - itkGetStringMacro(FilePrefix); - itkSetStringMacro(FilePattern); - itkGetStringMacro(FilePattern); - - virtual void EnlargeOutputRequestedRegion(itk::DataObject *output); +public: - static void ConvertHandedness(mitkIpPicDescriptor* pic); + PicFileReader(); - static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern); + using AbstractFileReader::Read; + std::vector Read(); protected: - virtual void GenerateData(); - - virtual void GenerateOutputInformation(); - - PicFileReader(); - - ~PicFileReader(); - //##Description - //## @brief Time when Header was last read - itk::TimeStamp m_ReadHeaderTime; + void FillImage(Image::Pointer image); - int m_StartFileIndex; + Image::Pointer CreateImage(); - std::string m_FileName; +private: - std::string m_FilePrefix; + static void ConvertHandedness(mitkIpPicDescriptor* pic); - std::string m_FilePattern; + PicFileReader* Clone() const; }; } // namespace mitk #endif /* PICFILEREADER_H_HEADER_INCLUDED_C1F48A22 */ diff --git a/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesIOFactory.cpp b/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesIOFactory.cpp deleted file mode 100644 index 061b94e7f9..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesIOFactory.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/*=================================================================== - -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 "mitkPicVolumeTimeSeriesIOFactory.h" -#include "mitkIOAdapter.h" -#include "mitkPicVolumeTimeSeriesReader.h" - -#include "itkVersion.h" - - -namespace mitk -{ -PicVolumeTimeSeriesIOFactory::PicVolumeTimeSeriesIOFactory() -{ - this->RegisterOverride("mitkIOAdapter", - "mitkPicVolumeTimeSeriesReader", - "mitk Pic Image IO", - 1, - itk::CreateObjectFunction >::New()); -} - -PicVolumeTimeSeriesIOFactory::~PicVolumeTimeSeriesIOFactory() -{ -} - -const char* PicVolumeTimeSeriesIOFactory::GetITKSourceVersion() const -{ - return ITK_SOURCE_VERSION; -} - -const char* PicVolumeTimeSeriesIOFactory::GetDescription() const -{ - return "PicVolumeTimeSeries IO Factory, allows the loading of DKFZ Pic images"; -} - -} // end namespace mitk diff --git a/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesIOFactory.h b/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesIOFactory.h deleted file mode 100644 index 8d961036c1..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesIOFactory.h +++ /dev/null @@ -1,70 +0,0 @@ -/*=================================================================== - -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 __mitkPicVolumeTimeSeriesIOFactory_h -#define __mitkPicVolumeTimeSeriesIOFactory_h - -#ifdef _MSC_VER -#pragma warning ( disable : 4786 ) -#endif - -#include "itkObjectFactoryBase.h" -#include "mitkBaseData.h" - -namespace mitk -{ -//##Documentation -//## @brief Create instances of PicVolumeTimeSeriesReader objects using an object factory. -//## -class PicVolumeTimeSeriesIOFactory : public itk::ObjectFactoryBase -{ -public: - /** Standard class typedefs. */ - typedef PicVolumeTimeSeriesIOFactory Self; - typedef itk::ObjectFactoryBase Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; - - /** Class methods used to interface with the registered factories. */ - virtual const char* GetITKSourceVersion(void) const; - virtual const char* GetDescription(void) const; - - /** Method for class instantiation. */ - itkFactorylessNewMacro(Self); - static PicVolumeTimeSeriesIOFactory* FactoryNew() { return new PicVolumeTimeSeriesIOFactory;} - /** Run-time type information (and related methods). */ - itkTypeMacro(PicVolumeTimeSeriesIOFactory, ObjectFactoryBase); - - /** Register one factory of this type */ - static void RegisterOneFactory(void) - { - PicVolumeTimeSeriesIOFactory::Pointer PicVolumeTimeSeriesIOFactory = PicVolumeTimeSeriesIOFactory::New(); - ObjectFactoryBase::RegisterFactory(PicVolumeTimeSeriesIOFactory); - } - -protected: - PicVolumeTimeSeriesIOFactory(); - ~PicVolumeTimeSeriesIOFactory(); - -private: - PicVolumeTimeSeriesIOFactory(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented - -}; - - -} // end namespace mitk - -#endif diff --git a/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesReader.cpp b/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesReader.cpp deleted file mode 100644 index 3f5767a190..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesReader.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/*=================================================================== - -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 "mitkPicVolumeTimeSeriesReader.h" -#include "mitkPicFileReader.h" -#include -#include - -#include - -extern "C" -{ -mitkIpPicDescriptor * MITKipPicGet( char *infile_name, mitkIpPicDescriptor *pic ); -mitkIpPicDescriptor * MITKipPicGetTags( char *infile_name, mitkIpPicDescriptor *pic ); -} - - -void mitk::PicVolumeTimeSeriesReader::GenerateOutputInformation() -{ - mitk::Image::Pointer output = this->GetOutput(); - - if ( ( output->IsInitialized() ) && ( this->GetMTime() <= m_ReadHeaderTime.GetMTime() ) ) - return ; - - itkDebugMacro( << "Reading file for GenerateOutputInformation()" << m_FileName ); - - if ( ! this->GenerateFileList() ) - { - itkWarningMacro( "Sorry, file list could not be generated!" ); - return ; - } - - // - // Read the first file of the image sequence. Assume equal size and spacings for all - // other volumes. @TODO Integrate support for different sizes and spacings - // - char* filename = const_cast ( m_MatchedFileNames[ 0 ].c_str() ); - mitkIpPicDescriptor * header = mitkIpPicGetHeader( filename, NULL ); - header = MITKipPicGetTags( filename, header ); - - if ( header == NULL ) - { - itk::ImageFileReaderException e( __FILE__, __LINE__ ); - std::ostringstream msg; - msg << " Could not read file " << m_FileName.c_str(); - e.SetDescription( msg.str().c_str() ); - throw e; - return ; - } - if ( header->dim != 3 ) - { - itk::ImageFileReaderException e( __FILE__, __LINE__ , "Only 3D-pic volumes are supported! " ); - throw e; - return ; - } - - // - // modify the header to match the real temporal extent - // - header->dim = 4; - header->n[ 3 ] = m_MatchedFileNames.size(); - - output->Initialize( CastToImageDescriptor( header) ); - - mitkIpPicFree( header ); - - m_ReadHeaderTime.Modified(); -} - - -void mitk::PicVolumeTimeSeriesReader::GenerateData() -{ - mitk::Image::Pointer output = this->GetOutput(); - - // - // Check to see if we can read the file given the name or prefix - // - if ( m_FilePrefix == "" || m_FilePattern == "" ) - { - throw itk::ImageFileReaderException( __FILE__, __LINE__, "Both FilePattern and FilePrefix must be non-empty" ); - } - - if ( m_MatchedFileNames.size() == 0 ) - { - throw itk::ImageFileReaderException( __FILE__, __LINE__, "Sorry, there are no files to read!" ); - } - - - // - // read 3d volumes and copy them to the 4d volume - // - mitkIpPicDescriptor* volume3d = NULL; - for ( unsigned int t = 0 ; t < m_MatchedFileNames.size() ; ++t ) - { - char* filename = const_cast< char* >( m_MatchedFileNames[ t ].c_str() ); - MITK_INFO << "Reading file " << filename << "..." << std::endl; - volume3d = MITKipPicGet( filename, NULL ); - - if ( volume3d == NULL ) - { - std::ostringstream message; - message << "mitk::ERROR: " << this->GetNameOfClass() << "(" << this << "): " - << "File (" << filename << ") of time frame " << t << " could not be read!"; - throw itk::ImageFileReaderException( __FILE__, __LINE__, message.str().c_str() ); - } - - // - // @TODO do some error checking - // - - // - // copy the 3d data volume to the 4d volume - // - - // \todo use memory of Image as in PicFileReader (or integrate everything into the PicFileReader!) - PicFileReader::ConvertHandedness(volume3d); - bool result = false; - // FIXME - //result = output->SetPicVolume( volume3d, t ); - if(result==false) - { - std::ostringstream message; - message << "mitk::ERROR: " << this->GetNameOfClass() << "(" << this << "): " - << "Volume of time frame " << t << " did not match size of other time frames."; - throw itk::ImageFileReaderException( __FILE__, __LINE__, message.str().c_str() ); - } - mitkIpPicFree ( volume3d ); - } -} - -bool mitk::PicVolumeTimeSeriesReader::CanReadFile(const std::string /*filename*/, const std::string filePrefix, const std::string filePattern) -{ - if( filePattern == "" && filePrefix == "" ) - return false; - - bool extensionFound = false; - std::string::size_type PICPos = filePattern.rfind(".pic"); - if ((PICPos != std::string::npos) - && (PICPos == filePattern.length() - 4)) - { - extensionFound = true; - } - - PICPos = filePattern.rfind(".pic.gz"); - if ((PICPos != std::string::npos) - && (PICPos == filePattern.length() - 7)) - { - extensionFound = true; - } - - if( !extensionFound ) - return false; - - return true; -} - -mitk::PicVolumeTimeSeriesReader::PicVolumeTimeSeriesReader() -{ - //this->DebugOn(); -} - -mitk::PicVolumeTimeSeriesReader::~PicVolumeTimeSeriesReader() -{} diff --git a/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesReader.h b/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesReader.h deleted file mode 100644 index 42d96e4e09..0000000000 --- a/Modules/IpPicSupportIO/Internal/mitkPicVolumeTimeSeriesReader.h +++ /dev/null @@ -1,66 +0,0 @@ -/*=================================================================== - -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 _PIC_VOLUME_TIME_SERIES_READER__H_ -#define _PIC_VOLUME_TIME_SERIES_READER__H_ - -#include "mitkFileSeriesReader.h" -#include "mitkImageSource.h" -#include - -namespace mitk -{ -//##Documentation -//## @brief Reader to read a series of volume files in DKFZ-pic-format -class PicVolumeTimeSeriesReader : public ImageSource, public FileSeriesReader -{ -public: - mitkClassMacro( PicVolumeTimeSeriesReader, FileReader ); - - /** Method for creation through the object factory. */ - itkFactorylessNewMacro(Self) - itkCloneMacro(Self) - - itkSetStringMacro(FileName); - itkGetStringMacro(FileName); - - itkSetStringMacro(FilePrefix); - itkGetStringMacro(FilePrefix); - - itkSetStringMacro(FilePattern); - itkGetStringMacro(FilePattern); - - static bool CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern); - -protected: - virtual void GenerateData(); - - virtual void GenerateOutputInformation(); - - PicVolumeTimeSeriesReader(); - - ~PicVolumeTimeSeriesReader(); - - //##Description - //## @brief Time when Header was last read - itk::TimeStamp m_ReadHeaderTime; - -}; - -} // namespace mitk - -#endif diff --git a/Modules/IpPicSupportIO/files.cmake b/Modules/IpPicSupportIO/files.cmake index 22d9d1891d..0bbfe7f0c5 100644 --- a/Modules/IpPicSupportIO/files.cmake +++ b/Modules/IpPicSupportIO/files.cmake @@ -1,8 +1,6 @@ set(CPP_FILES Internal/mitkIpPicGet.c + Internal/mitkIpPicSupportIOActivator.cpp Internal/mitkPicFileReader.cpp - Internal/mitkPicFileIOFactory.cpp Internal/mitkPicHelper.cpp - Internal/mitkPicVolumeTimeSeriesIOFactory.cpp - Internal/mitkPicVolumeTimeSeriesReader.cpp ) diff --git a/Modules/LegacyIO/files.cmake b/Modules/LegacyIO/files.cmake index aacea1ec18..5790303f08 100644 --- a/Modules/LegacyIO/files.cmake +++ b/Modules/LegacyIO/files.cmake @@ -1,31 +1,30 @@ set(H_FILES ) set(CPP_FILES - mitkActivator.cpp mitkBaseDataIOFactory.cpp mitkDataNodeFactory.cpp mitkFileSeriesReader.cpp mitkImageWriter.cpp mitkImageWriterFactory.cpp mitkItkImageFileIOFactory.cpp mitkItkImageFileReader.cpp mitkItkPictureWrite.cpp mitkPointSetIOFactory.cpp mitkPointSetReader.cpp mitkPointSetWriter.cpp mitkPointSetWriterFactory.cpp mitkRawImageFileReader.cpp mitkSTLFileIOFactory.cpp mitkSTLFileReader.cpp mitkSurfaceVtkWriter.cpp mitkSurfaceVtkWriterFactory.cpp mitkVtiFileIOFactory.cpp mitkVtiFileReader.cpp mitkVtkImageIOFactory.cpp mitkVtkImageReader.cpp mitkVtkSurfaceIOFactory.cpp mitkVtkSurfaceReader.cpp vtkPointSetXMLParser.cpp ) diff --git a/Modules/LegacyIO/mitkActivator.cpp b/Modules/LegacyIO/mitkActivator.cpp deleted file mode 100644 index b50a1ebe9b..0000000000 --- a/Modules/LegacyIO/mitkActivator.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/*=================================================================== - -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 "mitkSurfaceVtkWriterFactory.h" -#include "mitkPointSetIOFactory.h" -#include "mitkPointSetWriterFactory.h" -#include "mitkSTLFileIOFactory.h" -#include "mitkVtkSurfaceIOFactory.h" -#include "mitkVtkImageIOFactory.h" -#include "mitkVtiFileIOFactory.h" -#include "mitkItkImageFileIOFactory.h" -#include "mitkImageWriterFactory.h" -#include "mitkCoreObjectFactoryBase.h" -#include "mitkCoreObjectFactory.h" -#include "mitkSurfaceVtkWriter.h" - -#include -#include - -namespace mitk { - -class LegacyIOObjectFactory : public CoreObjectFactoryBase -{ - public: - mitkClassMacro(LegacyIOObjectFactory,CoreObjectFactoryBase) - itkFactorylessNewMacro(Self) - itkCloneMacro(Self) - - virtual Mapper::Pointer CreateMapper(mitk::DataNode* /*node*/, MapperSlotId /*slotId*/) - { - return Mapper::Pointer(); - } - - virtual void SetDefaultProperties(mitk::DataNode* /*node*/) - { - } - - virtual const char* GetFileExtensions() - { - return ""; - } - - virtual mitk::CoreObjectFactoryBase::MultimapType GetFileExtensionsMap() - { - return m_FileExtensionsMap; - } - - virtual const char* GetSaveFileExtensions() - { - std::string fileExtension; - this->CreateFileExtensions(m_SaveFileExtensionsMap, fileExtension); - return fileExtension.c_str(); - } - - virtual mitk::CoreObjectFactoryBase::MultimapType GetSaveFileExtensionsMap() - { - return m_SaveFileExtensionsMap; - } - - ~LegacyIOObjectFactory() - { - for(std::vector::const_iterator iter = m_ObjectFactories.begin(), - end = m_ObjectFactories.end(); iter != end; ++iter) - { - itk::ObjectFactoryBase::UnRegisterFactory(*iter); - } - } - -protected: - - LegacyIOObjectFactory() - : CoreObjectFactoryBase() - { - m_ObjectFactories.push_back(mitk::PointSetIOFactory::New().GetPointer()); - m_ObjectFactories.push_back(mitk::STLFileIOFactory::New().GetPointer()); - m_ObjectFactories.push_back(mitk::VtkSurfaceIOFactory::New().GetPointer()); - m_ObjectFactories.push_back(mitk::VtkImageIOFactory::New().GetPointer()); - m_ObjectFactories.push_back(mitk::VtiFileIOFactory::New().GetPointer()); - m_ObjectFactories.push_back(mitk::ItkImageFileIOFactory::New().GetPointer()); - - for(std::vector::const_iterator iter = m_ObjectFactories.begin(), - end = m_ObjectFactories.end(); iter != end; ++iter) - { - itk::ObjectFactoryBase::RegisterFactory(*iter); - } - - m_FileWriters.push_back(mitk::SurfaceVtkWriter::New().GetPointer()); - m_FileWriters.push_back(mitk::SurfaceVtkWriter::New().GetPointer()); - m_FileWriters.push_back(mitk::SurfaceVtkWriter::New().GetPointer()); - //m_FileWriters.push_back(mitk::PointSetWriterFactory::New().GetPointer()); - //m_FileWriters.push_back(mitk::ImageWriterFactory::New().GetPointer()); - - this->CreateFileExtensionsMap(); - } - - void CreateFileExtensionsMap() - { - m_SaveFileExtensionsMap.insert(std::pair("*.stl", "STL Surface File")); - m_SaveFileExtensionsMap.insert(std::pair("*.obj", "Surface File")); - m_SaveFileExtensionsMap.insert(std::pair("*.vtk", "VTK Surface File")); - m_SaveFileExtensionsMap.insert(std::pair("*.vtp", "VTK Polydata File")); - } - - MultimapType m_FileExtensionsMap; - MultimapType m_SaveFileExtensionsMap; - -private: - - std::string m_ExternalFileExtensions; - std::string m_InternalFileExtensions; - std::string m_SaveFileExtensions; - - std::vector m_ObjectFactories; -}; - -} - -class US_ABI_LOCAL Activator : public us::ModuleActivator -{ -public: - - void Load(us::ModuleContext* context) - { - m_Factory = mitk::LegacyIOObjectFactory::New(); - mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(m_Factory); - } - - void Unload(us::ModuleContext* ) - { - mitk::CoreObjectFactory::GetInstance()->UnRegisterExtraFactory(m_Factory); - } - -private: - - //std::auto_ptr m_CoreDataNodeReader; - - us::ModuleContext* m_Context; - - mitk::LegacyIOObjectFactory::Pointer m_Factory; -}; - -US_EXPORT_MODULE_ACTIVATOR(MitkLegacyIO, Activator) diff --git a/Modules/QtWidgets/QmitkIOUtil.cpp b/Modules/QtWidgets/QmitkIOUtil.cpp index b78b343d6b..d69d66a633 100644 --- a/Modules/QtWidgets/QmitkIOUtil.cpp +++ b/Modules/QtWidgets/QmitkIOUtil.cpp @@ -1,528 +1,527 @@ /*=================================================================== 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 "mitkMimeType.h" #include "mitkCustomMimeType.h" #include "mitkFileReaderRegistry.h" #include "mitkFileWriterRegistry.h" #include "QmitkFileReaderOptionsDialog.h" #include "QmitkFileWriterOptionsDialog.h" // QT #include #include #include #include //ITK #include #include struct QmitkIOUtil::Impl { struct ReaderOptionsDialogFunctor : public ReaderOptionsFunctorBase { virtual bool operator()(LoadInfo& loadInfo) { QmitkFileReaderOptionsDialog dialog(loadInfo); if (dialog.exec() == QDialog::Accepted) { return !dialog.ReuseOptions(); } else { loadInfo.m_Cancel = true; return true; } } }; struct WriterOptionsDialogFunctor : public WriterOptionsFunctorBase { virtual bool operator()(SaveInfo& saveInfo) { QmitkFileWriterOptionsDialog dialog(saveInfo); if (dialog.exec() == QDialog::Accepted) { return !dialog.ReuseOptions(); } else { saveInfo.m_Cancel = true; return true; } } }; }; struct MimeTypeComparison : public std::unary_function { MimeTypeComparison(const std::string& mimeTypeName) : m_Name(mimeTypeName) {} bool operator()(const mitk::MimeType& mimeType) const { return mimeType.GetName() == m_Name; } const std::string m_Name; }; QString QmitkIOUtil::GetFileOpenFilterString() { QString filters; mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); std::vector categories = mimeTypeProvider->GetCategories(); 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 = mt->GetExtensions(); 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; } QList QmitkIOUtil::Load(const QStringList& paths, QWidget* parent) { std::vector loadInfos; foreach(const QString& file, paths) { loadInfos.push_back(LoadInfo(file.toStdString())); } Impl::ReaderOptionsDialogFunctor optionsCallback; std::string errMsg = Load(loadInfos, 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 = loadInfos.begin(), iterEnd = loadInfos.end(); iter != iterEnd; ++iter) { for (std::vector::const_iterator dataIter = iter->m_Output.begin(), dataIterEnd = iter->m_Output.end(); dataIter != dataIterEnd; ++dataIter) { qResult << *dataIter; } } return qResult; } mitk::DataStorage::SetOfObjects::Pointer QmitkIOUtil::Load(const QStringList& paths, mitk::DataStorage& storage, QWidget* parent) { std::vector loadInfos; foreach(const QString& file, paths) { loadInfos.push_back(LoadInfo(file.toStdString())); } mitk::DataStorage::SetOfObjects::Pointer nodeResult = mitk::DataStorage::SetOfObjects::New(); Impl::ReaderOptionsDialogFunctor optionsCallback; std::string errMsg = Load(loadInfos, 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) { SaveInfo saveInfo(*dataIter, mitk::MimeType(), std::string()); SaveFilter filters(saveInfo); // 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]; // We do not append an extension to the file name by default. The extension // is chosen by the user by either selecting a filter or writing the // extension in the file name himself (in the file save dialog). /* QString defaultExt = filters.GetDefaultExtension(); if (!defaultExt.isEmpty()) { fileName += "." + defaultExt; } */ } // Ask the user for a file name QString nextName = QFileDialog::getSaveFileName(parent, dialogTitle, fileName, filterString, &selectedFilter); if (nextName.isEmpty()) { // We stop asking for further file names, but we still save the // data where the user already confirmed the save dialog. break; } fileName = nextName; QFileInfo fileInfo(fileName); currentPath = fileInfo.absolutePath(); QString suffix = fileInfo.completeSuffix(); mitk::MimeType 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 = mitk::MimeType(); for (std::vector::const_iterator availIter = availableTypes.begin(), availIterEnd = availableTypes.end(); availIter != availIterEnd; ++availIter) { if (filters.ContainsMimeType(availIter->GetName())) { mimeType = *availIter; break; } } } if (!mimeType.IsValid()) { // 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(mimeType.GetExtensions().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 (QMessageBox::question(parent, "Replace File", QString("A file named \"%1\" already exists. Do you want to replace it?").arg(fileName)) == 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); saveInfo.m_Path = fileName.toStdString(); saveInfo.m_MimeType = mimeType; // pre-select the best writer for the chosen mime-type saveInfo.m_WriterSelector.Select(mimeType.GetName()); saveInfos.push_back(saveInfo); - MITK_INFO << "****** SAVING TO FILENAME: " << fileName.toStdString(); } if (!saveInfos.empty()) { 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 { Impl(const mitk::IOUtil::SaveInfo& saveInfo) : m_SaveInfo(saveInfo) { // 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 // (this is sorted already) std::vector mimeTypes = saveInfo.m_WriterSelector.GetMimeTypes(); for (std::vector::const_reverse_iterator iter = mimeTypes.rbegin(), iterEnd = mimeTypes.rend(); iter != iterEnd; ++iter) { QSet filterExtensions; mitk::MimeType mimeType = *iter; std::vector extensions = mimeType.GetExtensions(); for (std::vector::iterator extIter = extensions.begin(), extIterEnd = extensions.end(); extIter != extIterEnd; ++extIter) { filterExtensions << QString::fromStdString(*extIter); } if (m_DefaultExtension.isEmpty()) { m_DefaultExtension = QString::fromStdString(extensions.front()); } QString filter = QString::fromStdString(mimeType.GetComment()) + " ("; foreach(const QString& extension, filterExtensions) { filter += "*." + extension + " "; } filter = filter.replace(filter.size()-1, 1, ')'); m_MimeTypes.push_back(mimeType); m_FilterStrings.push_back(filter); } } const mitk::IOUtil::SaveInfo m_SaveInfo; std::vector m_MimeTypes; QStringList m_FilterStrings; QString m_DefaultExtension; }; mitk::MimeType QmitkIOUtil::SaveFilter::ALL_MIMETYPE() { static mitk::CustomMimeType allMimeType(std::string("__all__")); return mitk::MimeType(allMimeType, -1, -1); } QmitkIOUtil::SaveFilter::SaveFilter(const QmitkIOUtil::SaveFilter& other) : d(new Impl(*other.d)) { } QmitkIOUtil::SaveFilter::SaveFilter(const SaveInfo& saveInfo) : d(new Impl(saveInfo)) { } 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_if(d->m_MimeTypes.begin(), d->m_MimeTypes.end(), MimeTypeComparison(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]; } mitk::MimeType QmitkIOUtil::SaveFilter::GetMimeTypeForFilter(const QString& filter) const { int index = d->m_FilterStrings.indexOf(filter); if (index < 0) { return mitk::MimeType(); } 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(); } QString QmitkIOUtil::SaveFilter::GetDefaultExtension() const { return d->m_DefaultExtension; } mitk::MimeType 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 mitk::MimeType(); } 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_if(d->m_MimeTypes.begin(), d->m_MimeTypes.end(), MimeTypeComparison(mimeType)) != d->m_MimeTypes.end(); } diff --git a/Modules/SceneSerialization/Testing/mitkSceneIOTest.cpp b/Modules/SceneSerialization/Testing/mitkSceneIOTest.cpp index f2aa092419..84fed0d84a 100644 --- a/Modules/SceneSerialization/Testing/mitkSceneIOTest.cpp +++ b/Modules/SceneSerialization/Testing/mitkSceneIOTest.cpp @@ -1,346 +1,322 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTestingMacros.h" #include "mitkTestingConfig.h" #include "mitkSceneIO.h" #include "mitkStandaloneDataStorage.h" #include "mitkStandardFileLocations.h" -#include "mitkDataNodeFactory.h" #include "mitkCoreObjectFactory.h" #include "mitkBaseData.h" #include "mitkImage.h" #include "mitkSurface.h" #include "mitkPointSet.h" +#include "mitkIOUtil.h" #include "Poco/File.h" #include "Poco/TemporaryFile.h" #ifndef WIN32 #include #include #endif class SceneIOTestClass { public: -static mitk::BaseData::Pointer LoadBaseData(const std::string& filename) -{ - mitk::DataNodeFactory::Pointer factory = mitk::DataNodeFactory::New(); - try - { - factory->SetFileName( filename ); - factory->Update(); - - if(factory->GetNumberOfOutputs()<1) - { - MITK_TEST_FAILED_MSG(<< "Could not find test data '" << filename << "'"); - } - - mitk::DataNode::Pointer node = factory->GetOutput( 0 ); - return node->GetData(); - } - catch ( itk::ExceptionObject & e ) - { - MITK_TEST_FAILED_MSG(<< "Failed loading test data '" << filename << "': " << e.what()); - } -} - static mitk::Image::Pointer LoadImage(const std::string& filename) { - mitk::BaseData::Pointer basedata = LoadBaseData( filename ); - mitk::Image::Pointer image = dynamic_cast(basedata.GetPointer()); + mitk::Image::Pointer image = mitk::IOUtil::LoadImage( filename ); if(image.IsNull()) { MITK_TEST_FAILED_MSG(<< "Test image '" << filename << "' was not loaded as an mitk::Image"); } return image; } static mitk::Surface::Pointer LoadSurface(const std::string& filename) { - mitk::BaseData::Pointer basedata = LoadBaseData( filename ); - mitk::Surface::Pointer surface = dynamic_cast(basedata.GetPointer()); + mitk::Surface::Pointer surface = mitk::IOUtil::LoadSurface( filename ); if(surface.IsNull()) { MITK_TEST_FAILED_MSG(<< "Test surface '" << filename << "' was not loaded as an mitk::Surface"); } return surface; } static mitk::PointSet::Pointer CreatePointSet() { mitk::PointSet::Pointer ps = mitk::PointSet::New(); mitk::PointSet::PointType p; mitk::FillVector3D(p, 1.0, -2.0, 33.0); ps->SetPoint(0, p); mitk::FillVector3D(p, 100.0, -200.0, 3300.0); ps->SetPoint(1, p); mitk::FillVector3D(p, 2.0, -3.0, 22.0); ps->SetPoint(2, p, mitk::PTCORNER); // add point spec //mitk::FillVector3D(p, -2.0, -2.0, -2.22); //ps->SetPoint(0, p, 1); // ID 0 in timestep 1 //mitk::FillVector3D(p, -1.0, -1.0, -11.22); //ps->SetPoint(1, p, 1); // ID 1 in timestep 1 //mitk::FillVector3D(p, 1000.0, 1000.0, 1122.22); //ps->SetPoint(11, p, mitk::PTCORNER, 2); // ID 11, point spec, timestep 2 return ps; } static void FillStorage(mitk::DataStorage* storage, std::string imageName, std::string surfaceName) { mitk::Image::Pointer image = LoadImage(imageName); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(),"Loading test image"+imageName); image->SetProperty("image type", mitk::StringProperty::New("test image") ); image->SetProperty("greetings", mitk::StringProperty::New("to mom") ); image->SetProperty("test_float_property", mitk::FloatProperty::New(-2.57f)); mitk::DataNode::Pointer imagenode = mitk::DataNode::New(); imagenode->SetData( image ); imagenode->SetName( "Pic3D" ); storage->Add( imagenode ); mitk::DataNode::Pointer imagechildnode = mitk::DataNode::New(); imagechildnode->SetData( image ); imagechildnode->SetName( "Pic3D again" ); storage->Add( imagechildnode, imagenode ); mitk::Surface::Pointer surface = LoadSurface(surfaceName ); MITK_TEST_CONDITION_REQUIRED(surface.IsNotNull(),"Loading test surface binary.stl"); surface->SetProperty("surface type", mitk::StringProperty::New("test surface") ); surface->SetProperty("greetings", mitk::StringProperty::New("to dad") ); mitk::DataNode::Pointer surfacenode = mitk::DataNode::New(); surfacenode->SetData( surface ); surfacenode->SetName( "binary" ); storage->Add( surfacenode ); mitk::PointSet::Pointer ps = CreatePointSet(); mitk::DataNode::Pointer psenode = mitk::DataNode::New(); psenode->SetData( ps ); psenode->SetName( "points" ); storage->Add( psenode ); } static void VerifyStorage(mitk::DataStorage* storage) { //TODO the Surface and PointSet are uncommented until the material property is saved properly mitk::DataNode::Pointer imagenode = storage->GetNamedNode("Pic3D"); MITK_TEST_CONDITION_REQUIRED(imagenode.IsNotNull(),"Get previously stored image node"); mitk::Image::Pointer image = dynamic_cast(imagenode->GetData()); MITK_TEST_CONDITION_REQUIRED(image.IsNotNull(),"Loading test image from Datastorage"); //Image std::string testString(""); float testFloatValue = 0.0f; mitk::PropertyList::Pointer imagePropList = image->GetPropertyList(); imagePropList->GetStringProperty("image type", testString); MITK_TEST_CONDITION(testString == "test image" ,"Get StringProperty from previously stored image"); imagePropList->GetStringProperty("greetings", testString); MITK_TEST_CONDITION(testString == "to mom" ,"Get another StringProperty from previously stored image"); imagePropList->GetFloatProperty("test_float_property", testFloatValue); MITK_TEST_CONDITION(testFloatValue == -2.57f, "Get FloatProperty from previously stored image.") //Get Image child node mitk::DataNode::Pointer imagechildnode = storage->GetNamedNode("Pic3D again"); mitk::DataStorage::SetOfObjects::ConstPointer objects = storage->GetSources(imagechildnode); MITK_TEST_CONDITION_REQUIRED(objects->Size() == 1,"Check size of image child nodes source list"); MITK_TEST_CONDITION_REQUIRED(objects->ElementAt(0) == imagenode,"Check for right parent node"); mitk::Image::Pointer imagechild = dynamic_cast(imagechildnode->GetData()); MITK_TEST_CONDITION_REQUIRED(imagechild.IsNotNull(),"Loading child test image from Datastorage"); //Surface mitk::DataNode::Pointer surfacenode = storage->GetNamedNode("binary"); MITK_TEST_CONDITION_REQUIRED(surfacenode.IsNotNull(),"Get previously stored surface node"); mitk::Surface::Pointer surface = dynamic_cast(surfacenode->GetData()); MITK_TEST_CONDITION_REQUIRED(surface.IsNotNull(),"Loading test surface from Datastorage"); // Get the property list and test the properties mitk::PropertyList::Pointer surfacePropList = surface->GetPropertyList(); surfacePropList->GetStringProperty("surface type", testString); MITK_TEST_CONDITION((testString.compare("test surface") == 0) ,"Get StringProperty from previously stored surface node"); surfacePropList->GetStringProperty("greetings", testString); MITK_TEST_CONDITION((testString.compare("to dad") == 0) ,"Get another StringProperty from previously stored surface node"); //PointSet mitk::DataNode::Pointer pointsnode = storage->GetNamedNode("points"); MITK_TEST_CONDITION_REQUIRED(pointsnode.IsNotNull(),"Get previously stored PointSet node"); mitk::PointSet::Pointer pointset = dynamic_cast(pointsnode->GetData()); MITK_TEST_CONDITION_REQUIRED(pointset.IsNotNull(),"Loading test PointSet from Datastorage"); mitk::PointSet::PointType p = pointset->GetPoint(0); MITK_TEST_CONDITION_REQUIRED(p[0] == 1.0 && p[1] == -2.0 && p[2] == 33.0, "Test Pointset entry 0 after loading"); p = pointset->GetPoint(1); MITK_TEST_CONDITION_REQUIRED(p[0] == 100.0 && p[1] == -200.0 && p[2] == 3300.0, "Test Pointset entry 1 after loading"); p = pointset->GetPoint(2); MITK_TEST_CONDITION_REQUIRED(p[0] == 2.0 && p[1] == -3.0 && p[2] == 22.0, "Test Pointset entry 2 after loading"); } }; // end test helper class int mitkSceneIOTest(int, char* argv[]) { MITK_TEST_BEGIN("SceneIO") std::string sceneFileName; for (unsigned int i = 0; i < 1; ++i) // TODO change to " < 2" to check cases where file system would be full { if (i == 1) { // call ulimit and restrict maximum file size to something small #ifndef WIN32 errno = 0; long int value = ulimit(UL_SETFSIZE, 1); MITK_TEST_CONDITION_REQUIRED( value != -1, "ulimit() returned with errno = " << errno ); #else continue; #endif } // create a data storage and fill it with some test data mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); MITK_TEST_CONDITION_REQUIRED(sceneIO.IsNotNull(),"SceneIO instantiation") mitk::DataStorage::Pointer storage = mitk::StandaloneDataStorage::New().GetPointer(); MITK_TEST_CONDITION_REQUIRED(storage.IsNotNull(),"StandaloneDataStorage instantiation"); std::cout << "ImageName: " << argv[1] << std::endl; std::cout << "SurfaceName: " << argv[2] << std::endl; SceneIOTestClass::FillStorage(storage, argv[1], argv[2]); // attempt to save it Poco::Path newname( Poco::TemporaryFile::tempName() ); sceneFileName = std::string( MITK_TEST_OUTPUT_DIR ) + Poco::Path::separator() + newname.getFileName() + ".zip"; MITK_TEST_CONDITION_REQUIRED( sceneIO->SaveScene( storage->GetAll(), storage, sceneFileName), "Saving scene file '" << sceneFileName << "'"); // test if no errors were reported mitk::SceneIO::FailedBaseDataListType::ConstPointer failedNodes = sceneIO->GetFailedNodes(); if (failedNodes.IsNotNull() && !failedNodes->empty()) { MITK_TEST_OUTPUT( << "The following nodes could not be serialized:"); for ( mitk::SceneIO::FailedBaseDataListType::const_iterator iter = failedNodes->begin(); iter != failedNodes->end(); ++iter ) { MITK_TEST_OUTPUT_NO_ENDL( << " - "); if ( mitk::BaseData* data =(*iter)->GetData() ) { MITK_TEST_OUTPUT_NO_ENDL( << data->GetNameOfClass()); } else { MITK_TEST_OUTPUT_NO_ENDL( << "(NULL)"); } MITK_TEST_OUTPUT( << " contained in node '" << (*iter)->GetName() << "'"); // \TODO: should we fail the test case if failed properties exist? } } mitk::PropertyList::ConstPointer failedProperties = sceneIO->GetFailedProperties(); if (failedProperties.IsNotNull() && !failedProperties->IsEmpty()) { MITK_TEST_OUTPUT( << "The following properties could not be serialized:"); const mitk::PropertyList::PropertyMap* propmap = failedProperties->GetMap(); for ( mitk::PropertyList::PropertyMap::const_iterator iter = propmap->begin(); iter != propmap->end(); ++iter ) { MITK_TEST_OUTPUT( << " - " << iter->second->GetNameOfClass() << " associated to key '" << iter->first << "'"); // \TODO: should we fail the test case if failed properties exist? } } MITK_TEST_CONDITION_REQUIRED(failedProperties.IsNotNull() && failedProperties->IsEmpty(), "Checking if all properties have been saved.") MITK_TEST_CONDITION_REQUIRED(failedNodes.IsNotNull() && failedNodes->empty(), "Checking if all nodes have been saved.") //Now do the loading part sceneIO = mitk::SceneIO::New(); //Load scene into the datastorage and clean the DS first MITK_TEST_OUTPUT(<< "Loading scene again"); storage = sceneIO->LoadScene(sceneFileName,storage,true); // test if no errors were reported failedNodes = sceneIO->GetFailedNodes(); if (failedNodes.IsNotNull() && !failedNodes->empty()) { MITK_TEST_OUTPUT( << "The following nodes could not be serialized:"); for ( mitk::SceneIO::FailedBaseDataListType::const_iterator iter = failedNodes->begin(); iter != failedNodes->end(); ++iter ) { MITK_TEST_OUTPUT_NO_ENDL( << " - "); if ( mitk::BaseData* data =(*iter)->GetData() ) { MITK_TEST_OUTPUT_NO_ENDL( << data->GetNameOfClass()); } else { MITK_TEST_OUTPUT_NO_ENDL( << "(NULL)"); } MITK_TEST_OUTPUT( << " contained in node '" << (*iter)->GetName() << "'"); // \TODO: should we fail the test case if failed properties exist? } } failedProperties = sceneIO->GetFailedProperties(); if (failedProperties.IsNotNull() && !failedProperties->IsEmpty()) { MITK_TEST_OUTPUT( << "The following properties could not be serialized:"); const mitk::PropertyList::PropertyMap* propmap = failedProperties->GetMap(); for ( mitk::PropertyList::PropertyMap::const_iterator iter = propmap->begin(); iter != propmap->end(); ++iter ) { MITK_TEST_OUTPUT( << " - " << iter->second->GetNameOfClass() << " associated to key '" << iter->first << "'"); // \TODO: should we fail the test case if failed properties exist? } } // check if data storage content has been restored correctly SceneIOTestClass::VerifyStorage(storage); } // if no sub-test failed remove the scene file, otherwise it is kept for debugging purposes if ( mitk::TestManager::GetInstance()->NumberOfFailedTests() == 0 ) { Poco::File pocoSceneFile( sceneFileName ); MITK_TEST_CONDITION_REQUIRED( pocoSceneFile.exists(), "Checking if scene file still exists before cleaning up." ) pocoSceneFile.remove(); } MITK_TEST_END(); }