diff --git a/Core/Code/IO/mitkFileWriter.cpp b/Core/Code/IO/mitkFileWriter.cpp index 2ce7d530a4..7fbfc3159b 100644 --- a/Core/Code/IO/mitkFileWriter.cpp +++ b/Core/Code/IO/mitkFileWriter.cpp @@ -1,92 +1,97 @@ /*=================================================================== 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 "mitkFileWriter.h" bool mitk::FileWriter::CanWriteDataType( DataNode* ) { //TODO #345 check for writing permission return false; } std::string mitk::FileWriter::GetWritenMIMEType() { return ""; } +void mitk::FileWriter::SetInput(mitk::BaseData* data) +{ + this->SetNthInput(0, data); +} + std::string mitk::FileWriter::GetFileExtension() { return ""; } std::string mitk::FileWriter::GetPossibleFileExtensionsAsString() { std::vector possibleFileExtensions = this->GetPossibleFileExtensions(); std::stringstream stream; for (unsigned int i=0; i possibleFileExtensions = this->GetPossibleFileExtensions(); for (unsigned int i=0; i #include #include namespace mitk { //##Documentation //## @brief Interface class of writers that write data to files //## @ingroup Process //## @deprecatedSince{2014_03} Use mitk::IFileWriter instead. class MITK_CORE_EXPORT FileWriter : public itk::ProcessObject { public: mitkClassMacro(FileWriter,itk::ProcessObject); //##Documentation //## @brief Get the specified the file to write //## //## Either the FileName or FilePrefix plus FilePattern are used to write. virtual const char* GetFileName() const = 0; //##Documentation //## @brief Specify the file to write. //## //## Either the FileName or FilePrefix plus FilePattern are used to write. virtual void SetFileName(const char* aFileName) = 0; //##Documentation //## @brief Get the specified file prefix for the file(s) to write. //## //## You should specify either a FileName or FilePrefix. Use FilePrefix if //## the data is stored in multiple files. virtual const char* GetFilePrefix() const = 0; //##Documentation //## @brief Specify file prefix for the file(s) to write. //## //## You should specify either a FileName or FilePrefix. Use FilePrefix if //## the data is stored in multiple files. virtual void SetFilePrefix(const char* aFilePrefix) = 0; //##Documentation //## @brief Get the specified file pattern for the file(s) to write. The //## sprintf format used to build filename from FilePrefix and number. //## //## You should specify either a FileName or FilePrefix. Use FilePrefix if //## the data is stored in multiple files. virtual const char* GetFilePattern() const = 0; //##Documentation //## @brief Specified file pattern for the file(s) to write. The sprintf //## format used to build filename from FilePrefix and number. //## //## You should specify either a FileName or FilePrefix. Use FilePrefix if //## the data is stored in multiple files. virtual void SetFilePattern(const char* aFilePattern) = 0; //##Documentation //## @brief Return the extension to be added to the filename. virtual std::string GetFileExtension(); //##Documentation //## @brief Checks if given extension is valid for file writer bool IsExtensionValid(std::string extension); //##Documentation //## @brief Return the possible file extensions for the data type associated with the writer virtual std::vector GetPossibleFileExtensions() = 0; //##Documentation //## @brief possible file extensions for the data type associated with the writer as string virtual std::string GetPossibleFileExtensionsAsString(); //##Documentation //## @brief Check if the Writer can write this type of data of the //## DataTreenode. virtual bool CanWriteDataType( DataNode* ); //##Documentation //## @brief Return the MimeType of the saved File. virtual std::string GetWritenMIMEType(); + virtual std::string GetSupportedBaseData() const = 0; + + using ProcessObject::SetInput; + void SetInput( BaseData* data ); + virtual void Write() = 0; /** @brief Specifies, whether the file writer also can write a file to a memory buffer */ virtual bool CanWriteToMemory( ); /** @brief Set/Get functions to advise the file writer to use tis internal memory array as file writing destination*/ virtual void SetWriteToMemory( bool write ); virtual bool GetWriteToMemory( ); /** @brief To be used along with a call of SetWriteToMemory(true). This returns the memory buffer where the file was written.*/ virtual const char* GetMemoryPointer(); /** @brief To be used along with a call of SetWriteToMemory(true). This returns the size of the memory buffer where the file was written.*/ virtual unsigned int GetMemorySize(); /** @brief CAUTION: It's up to the user to call this function to release the memory buffer after use in case the file writer has written to its memory array.*/ virtual void ReleaseMemory(); protected: FileWriter(); virtual ~FileWriter(); bool m_CanWriteToMemory; bool m_WriteToMemory; char * m_MemoryBuffer; unsigned int m_MemoryBufferSize; }; #define mitkWriterMacro \ virtual void Write() \ { \ if ( this->GetInput() == NULL ) \ { \ itkExceptionMacro(<<"Write:Please specify an input!"); \ return; \ } \ /* Fill in image information.*/ \ this->UpdateOutputInformation(); \ (*(this->GetInputs().begin()))->SetRequestedRegionToLargestPossibleRegion();\ this->PropagateRequestedRegion(NULL); \ this->UpdateOutputData(NULL); \ } \ \ virtual void Update() \ { \ Write(); \ } } // namespace mitk #endif /* FILEWRITER_H_HEADER_INCLUDED */ diff --git a/Modules/IOExt/Internal/mitkUnstructuredGridVtkWriter.h b/Modules/IOExt/Internal/mitkUnstructuredGridVtkWriter.h index a561e8e368..19ec1e1b64 100644 --- a/Modules/IOExt/Internal/mitkUnstructuredGridVtkWriter.h +++ b/Modules/IOExt/Internal/mitkUnstructuredGridVtkWriter.h @@ -1,149 +1,152 @@ /*=================================================================== 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_UNSTRUCTURED_GRID_VTK_WRITER__H_ #define _MITK_UNSTRUCTURED_GRID_VTK_WRITER__H_ #include #include #include #include #include #include "mitkUnstructuredGrid.h" namespace mitk { /** * @brief VTK-based writer for mitk::UnstructuredGrid * * The mitk::UnstructuredGrid is written using the VTK-writer-type provided as the * template argument. If the mitk::UnstructuredGrid 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. */ template class UnstructuredGridVtkWriter : public mitk::FileWriterWithInformation { public: mitkClassMacro( UnstructuredGridVtkWriter, mitk::FileWriterWithInformation ); 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 ); using FileWriter::SetInput; /** * Sets the 0'th input object for the filter. * @param input the first input for the filter. */ void SetInput( BaseData* input ); /** * @returns the 0'th input object of the filter. */ const UnstructuredGrid* GetInput(); /** * Returns false if an error happened during writing */ itkGetMacro( Success, bool ); /** * @brief Return the possible file extensions for the data type associated with the writer */ virtual std::vector GetPossibleFileExtensions(); + virtual std::string GetSupportedBaseData() const + { return UnstructuredGrid::GetStaticNameOfClass(); } + // FileWriterWithInformation methods virtual const char * GetDefaultFilename(); virtual const char * GetFileDialogPattern(); virtual const char * GetDefaultExtension(); virtual bool CanWriteBaseDataType(BaseData::Pointer data); virtual void DoWrite(BaseData::Pointer data); protected: /** * Constructor. */ UnstructuredGridVtkWriter(); /** * Virtual destructor. */ virtual ~UnstructuredGridVtkWriter(); void ExecuteWrite(VTKWRITER* vtkWriter); virtual void GenerateData(); std::string m_FileName; std::string m_FilePrefix; std::string m_FilePattern; bool m_Success; }; } #endif // _MITK_UNSTRUCTURED_GRID_VTK_WRITER__H_ diff --git a/Modules/LegacyIO/mitkImageWriter.cpp b/Modules/LegacyIO/mitkImageWriter.cpp index f801418b0e..625fc892fb 100644 --- a/Modules/LegacyIO/mitkImageWriter.cpp +++ b/Modules/LegacyIO/mitkImageWriter.cpp @@ -1,496 +1,501 @@ /*=================================================================== 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 "mitkImageWriter.h" #include "mitkItkPictureWrite.h" #include "mitkImage.h" #include "mitkImageTimeSelector.h" #include "mitkImageAccessByItk.h" #include "mitkImageReadAccessor.h" #include #include mitk::ImageWriter::ImageWriter() : m_UseCompression( true ) { this->SetNumberOfRequiredInputs( 1 ); m_MimeType = ""; SetDefaultExtension(); } mitk::ImageWriter::~ImageWriter() { } void mitk::ImageWriter::SetFileName(const char* fileName) { if ( fileName && ( fileName == this->m_FileName ) ) { return; } if ( fileName ) { this->m_FileName = fileName; this->m_FileNameWithoutExtension = this->m_FileName; this->m_Extension.clear(); std::size_t pos = this->m_FileName.find_last_of("/\\"); if (pos != std::string::npos) { std::size_t ppos = this->m_FileName.find_first_of('.', pos); if (ppos != std::string::npos) { this->m_FileNameWithoutExtension = this->m_FileName.substr(0, ppos); this->m_Extension = this->m_FileName.substr(ppos); } } } else { this->m_FileName.clear(); this->m_FileNameWithoutExtension.clear(); this->m_Extension.clear(); } this->Modified(); } void mitk::ImageWriter::SetFileName(const std::string & fileName) { this->SetFileName( fileName.c_str() ); } void mitk::ImageWriter::SetExtension(const char* extension) { if ( extension && ( extension == this->m_Extension ) ) { return; } if ( extension ) { this->m_Extension = extension; this->m_FileName = this->m_FileNameWithoutExtension + this->m_Extension; } else { this->m_Extension.clear(); this->m_FileName = this->m_FileNameWithoutExtension; } this->Modified(); } void mitk::ImageWriter::SetExtension(const std::string & extension) { this->SetFileName( extension.c_str() ); } void mitk::ImageWriter::SetDefaultExtension() { this->m_Extension = ".mhd"; this->m_FileName = this->m_FileNameWithoutExtension + this->m_Extension; this->Modified(); } #include #include #include static void writeVti(const char * filename, mitk::Image* image, int t=0) { vtkXMLImageDataWriter * vtkwriter = vtkXMLImageDataWriter::New(); vtkwriter->SetFileName( filename ); vtkwriter->SetInputData(image->GetVtkImageData(t)); vtkwriter->Write(); vtkwriter->Delete(); } #include void mitk::ImageWriter::WriteByITK(mitk::Image* image, const std::string& fileName) { MITK_INFO << "Writing image: " << fileName << std::endl; // Pictures and picture series like .png are written via a different mechanism then volume images. // So, they are still multiplexed and thus not support vector images. if (fileName.find(".png") != std::string::npos || fileName.find(".tif") != std::string::npos || fileName.find(".jpg") != std::string::npos || fileName.find(".bmp") != std::string::npos) { try { // switch processing of single/multi-component images if( image->GetPixelType(0).GetNumberOfComponents() == 1) { AccessByItk_1( image, _mitkItkPictureWrite, fileName ); } else { AccessFixedPixelTypeByItk_1( image, _mitkItkPictureWriteComposite, MITK_ACCESSBYITK_PIXEL_TYPES_SEQ MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES_SEQ , fileName); } } catch(itk::ExceptionObject &e) { std::cerr << "Caught " << e.what() << std::endl; } catch(std::exception &e) { std::cerr << "Caught std::exception " << e.what() << std::endl; } return; } // Implementation of writer using itkImageIO directly. This skips the use // of templated itkImageFileWriter, which saves the multiplexing on MITK side. unsigned int dimension = image->GetDimension(); unsigned int* dimensions = image->GetDimensions(); mitk::PixelType pixelType = image->GetPixelType(); mitk::Vector3D mitkSpacing = image->GetGeometry()->GetSpacing(); mitk::Point3D mitkOrigin = image->GetGeometry()->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 an 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 an valid value here itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( fileName.c_str(), itk::ImageIOFactory::WriteMode ); if(imageIO.IsNull()) { itkExceptionMacro(<< "Error: Could not create itkImageIO via factory for file " << fileName); } // Set the necessary information for imageIO imageIO->SetNumberOfDimensions(dimension); imageIO->SetPixelType( pixelType.GetPixelType() ); imageIO->SetComponentType( pixelType.GetComponentType() < PixelComponentUserType ? static_cast(pixelType.GetComponentType()) : itk::ImageIOBase::UNKNOWNCOMPONENTTYPE); imageIO->SetNumberOfComponents( pixelType.GetNumberOfComponents() ); itk::ImageIORegion ioRegion( dimension ); for(unsigned int i=0; iSetDimensions(i,dimensions[i]); imageIO->SetSpacing(i,spacing4D[i]); imageIO->SetOrigin(i,origin4D[i]); mitk::Vector3D mitkDirection; mitkDirection.SetVnlVector(image->GetGeometry()->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< double > axisDirection(dimension); for(unsigned int j=0; jSetDirection( i, axisDirection ); ioRegion.SetSize(i, image->GetLargestPossibleRegion().GetSize(i) ); ioRegion.SetIndex(i, image->GetLargestPossibleRegion().GetIndex(i) ); } //use compression if available imageIO->SetUseCompression( m_UseCompression ); imageIO->SetIORegion(ioRegion); imageIO->SetFileName(fileName); ImageReadAccessor imageAccess(image); imageIO->Write(imageAccess.GetData()); } void mitk::ImageWriter::GenerateData() { 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; } } if ( m_FileName == "" ) { itkWarningMacro( << "Sorry, filename has not been set!" ); return ; } FILE* tempFile = fopen(m_FileName.c_str(),"w"); if (tempFile==NULL) { itkExceptionMacro(<<"File location not writeable"); return; } fclose(tempFile); remove(m_FileName.c_str()); // Creating clone of input image, since i might change the geometry mitk::Image::Pointer input = const_cast(this->GetInput())->Clone(); // Check if geometry information will be lost if (input->GetDimension() == 2) { if (!input->GetGeometry()->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 = input->GetGeometry()->GetSpacing(); mitk::Point3D origin = input->GetGeometry()->GetOrigin(); input->GetGeometry()->SetIndexToWorldTransform(affTrans); input->GetGeometry()->SetSpacing(spacing); input->GetGeometry()->SetOrigin(origin); } } bool vti = (m_Extension.find(".vti") != std::string::npos); // If the extension is NOT .pic and NOT .nrrd and NOT .nii and NOT .nii.gz the following block is entered if ( m_Extension.find(".pic") == std::string::npos && m_Extension.find(".nrrd") == std::string::npos && m_Extension.find(".nii") == std::string::npos && m_Extension.find(".nii.gz") == std::string::npos ) { if(input->GetDimension() > 3) { int t, timesteps; timesteps = input->GetDimension(3); ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New(); timeSelector->SetInput(input); mitk::Image::Pointer image = timeSelector->GetOutput(); for(t = 0; t < timesteps; ++t) { std::ostringstream filename; timeSelector->SetTimeNr(t); timeSelector->Update(); if(input->GetTimeGeometry()->IsValidTimeStep(t)) { const mitk::TimeBounds& timebounds = input->GetTimeGeometry()->GetTimeBounds(t); filename << m_FileNameWithoutExtension << "_S" << std::setprecision(0) << timebounds[0] << "_E" << std::setprecision(0) << timebounds[1] << "_T" << t << m_Extension; } else { itkWarningMacro(<<"Error on write: TimeGeometry invalid of image " << filename.str() << "."); filename << m_FileNameWithoutExtension << "_T" << t << m_Extension; } if ( vti ) { writeVti(filename.str().c_str(), input, t); } else { WriteByITK(image, filename.str()); } } } else if ( vti ) { writeVti(m_FileName.c_str(), input); } else { WriteByITK(input, m_FileName); } } else { // use the PicFileWriter for the .pic data type if( m_Extension.find(".pic") != std::string::npos ) { /* PicFileWriter::Pointer picWriter = PicFileWriter::New(); size_t found; found = m_FileName.find( m_Extension ); // !!! HAS to be at the very end of the filename (not somewhere in the middle) if( m_FileName.length() > 3 && found != m_FileName.length() - 4 ) { //if Extension not in Filename std::ostringstream filename; filename << m_FileName.c_str() << m_Extension; picWriter->SetFileName( filename.str().c_str() ); } else { picWriter->SetFileName( m_FileName.c_str() ); } picWriter->SetInputImage( input ); picWriter->Write(); */ } // use the ITK .nrrd Image writer if( m_Extension.find(".nrrd") != std::string::npos || m_Extension.find(".nii") != std::string::npos || m_Extension.find(".nii.gz") != std::string::npos ) { WriteByITK(input, this->m_FileName); } } m_MimeType = "application/MITK.Pic"; try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } } bool mitk::ImageWriter::CanWriteDataType( DataNode* input ) { if ( input ) { return this->CanWriteBaseDataType(input->GetData()); } return false; } void mitk::ImageWriter::SetInput( DataNode* input ) { if( input && CanWriteDataType( input ) ) this->ProcessObject::SetNthInput( 0, dynamic_cast( input->GetData() ) ); } std::string mitk::ImageWriter::GetWritenMIMEType() { return m_MimeType; } std::vector mitk::ImageWriter::GetPossibleFileExtensions() { std::vector possibleFileExtensions; possibleFileExtensions.push_back(".pic"); possibleFileExtensions.push_back(".pic.gz"); possibleFileExtensions.push_back(".bmp"); possibleFileExtensions.push_back(".dcm"); possibleFileExtensions.push_back(".DCM"); possibleFileExtensions.push_back(".dicom"); possibleFileExtensions.push_back(".DICOM"); possibleFileExtensions.push_back(".gipl"); possibleFileExtensions.push_back(".gipl.gz"); possibleFileExtensions.push_back(".mha"); possibleFileExtensions.push_back(".nii"); possibleFileExtensions.push_back(".nii.gz"); possibleFileExtensions.push_back(".nrrd"); possibleFileExtensions.push_back(".nhdr"); possibleFileExtensions.push_back(".png"); possibleFileExtensions.push_back(".PNG"); possibleFileExtensions.push_back(".spr"); possibleFileExtensions.push_back(".mhd"); possibleFileExtensions.push_back(".vtk"); possibleFileExtensions.push_back(".vti"); possibleFileExtensions.push_back(".hdr"); possibleFileExtensions.push_back(".img"); possibleFileExtensions.push_back(".img.gz"); possibleFileExtensions.push_back(".png"); possibleFileExtensions.push_back(".tif"); possibleFileExtensions.push_back(".jpg"); return possibleFileExtensions; } +std::string mitk::ImageWriter::GetSupportedBaseData() const +{ + return Image::GetStaticNameOfClass(); +} + std::string mitk::ImageWriter::GetFileExtension() { return m_Extension; } void mitk::ImageWriter::SetInput( mitk::Image* image ) { this->ProcessObject::SetNthInput( 0, image ); } const mitk::Image* mitk::ImageWriter::GetInput() { if ( this->GetNumberOfInputs() < 1 ) { return NULL; } else { return static_cast< const mitk::Image * >( this->ProcessObject::GetInput( 0 ) ); } } const char* mitk::ImageWriter::GetDefaultFilename() { return "Image.nrrd"; } const char* mitk::ImageWriter::GetFileDialogPattern() { return "Nearly Raw Raster Data (*.nrrd);;" "NIfTI format (*.nii *.nii.gz);;" "VTK Image Data Files (*.vti);;" "NRRD with detached header (*.nhdr);;" "Analyze Format (*.hdr);;" "MetaImage (*.mhd);;" "Sets of 2D slices (*.png *.tiff *.jpg *.jpeg *.bmp);;" "DICOM (*.dcm *.DCM *.dicom *.DICOM);;" "UMDS GIPL Format Files (*.gipl *.gipl.gz)"; } const char *mitk::ImageWriter::GetDefaultExtension() { return ".nrrd"; } bool mitk::ImageWriter::CanWriteBaseDataType(BaseData::Pointer data) { return dynamic_cast( data.GetPointer() ); } void mitk::ImageWriter::DoWrite(BaseData::Pointer data) { if (this->CanWriteBaseDataType(data)) { this->SetInput(dynamic_cast(data.GetPointer())); this->Update(); } } void mitk::ImageWriter::SetUseCompression( bool useCompression ) { m_UseCompression = useCompression; } diff --git a/Modules/LegacyIO/mitkImageWriter.h b/Modules/LegacyIO/mitkImageWriter.h index 3ef46d5f2d..7bc22220f6 100644 --- a/Modules/LegacyIO/mitkImageWriter.h +++ b/Modules/LegacyIO/mitkImageWriter.h @@ -1,177 +1,179 @@ /*=================================================================== 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_IMAGE_WRITER__H_ #define _MITK_IMAGE_WRITER__H_ #include #include namespace mitk { class Image; /** * @brief Writer for mitk::Image * * Uses the given extension (SetExtension) to decide the format to write * (.mhd is default, .pic, .tif, .png, .jpg supported yet). * @ingroup IO * @deprecatedSince{2014_03} Use mitk::IOUtils or mitk::FileWriterRegistry instead. */ class MitkLegacyIO_EXPORT ImageWriter : public mitk::FileWriterWithInformation { public: mitkClassMacro( ImageWriter, mitk::FileWriter ); itkFactorylessNewMacro(Self) itkCloneMacro(Self) mitkWriterMacro; /** * Sets the filename of the file to write. * @param _arg the name of the file to write. */ virtual void SetFileName (const char* fileName); virtual void SetFileName (const std::string& fileName); /** * @returns the name of the file to be written to disk. */ itkGetStringMacro( FileName ); /** * \brief Explicitly set the extension to be added to the filename. * @param _arg to be added to the filename, including a "." * (e.g., ".mhd"). */ virtual void SetExtension (const char* extension); virtual void SetExtension (const std::string& extension); /** * \brief Get the extension to be added to the filename. * @returns the extension to be added to the filename (e.g., * ".mhd"). */ itkGetStringMacro( Extension ); /** * \brief Set the extension to be added to the filename to the default */ void SetDefaultExtension(); /** * @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 SetInput( mitk::Image* input ); //##Documentation //## @brief Return the possible file extensions for the data type associated with the writer virtual std::vector GetPossibleFileExtensions(); + virtual std::string GetSupportedBaseData() const; + /** * @brief Return the extension to be added to the filename. */ virtual std::string GetFileExtension(); /** * @brief Check if the Writer can write the Content of the */ virtual bool CanWriteDataType( DataNode* ); /** * @brief Return the MimeType of the saved File. */ virtual std::string GetWritenMIMEType(); using Superclass::SetInput; /** * @brief Set the DataTreenode as Input. Important: The Writer always have a SetInput-Function. */ virtual void SetInput( DataNode* ); /** * @returns the 0'th input object of the filter. */ const mitk::Image* GetInput(); // FileWriterWithInformation methods virtual const char* GetDefaultFilename(); virtual const char *GetFileDialogPattern(); virtual const char *GetDefaultExtension(); virtual bool CanWriteBaseDataType(BaseData::Pointer data); virtual void DoWrite(BaseData::Pointer data); void SetUseCompression( bool useCompression ); protected: /** * Constructor. */ ImageWriter(); /** * Virtual destructor. */ virtual ~ImageWriter(); virtual void GenerateData(); virtual void WriteByITK(mitk::Image* image, const std::string& fileName); std::string m_FileName; std::string m_FileNameWithoutExtension; std::string m_FilePrefix; std::string m_FilePattern; std::string m_Extension; std::string m_MimeType; bool m_UseCompression; }; } #endif //_MITK_IMAGE_WRITER__H_ diff --git a/Modules/LegacyIO/mitkPointSetWriter.cpp b/Modules/LegacyIO/mitkPointSetWriter.cpp index ba4c069c84..2321ec940f 100644 --- a/Modules/LegacyIO/mitkPointSetWriter.cpp +++ b/Modules/LegacyIO/mitkPointSetWriter.cpp @@ -1,382 +1,387 @@ /*=================================================================== 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 "mitkPointSetWriter.h" #include #include #include // // Initialization of the xml tags. // const char* mitk::PointSetWriter::XML_POINT_SET_FILE = "point_set_file" ; const char* mitk::PointSetWriter::XML_FILE_VERSION = "file_version" ; const char* mitk::PointSetWriter::XML_POINT_SET = "point_set" ; const char* mitk::PointSetWriter::XML_TIME_SERIES = "time_series"; const char* mitk::PointSetWriter::XML_TIME_SERIES_ID = "time_series_id"; const char* mitk::PointSetWriter::XML_POINT = "point" ; const char* mitk::PointSetWriter::XML_ID = "id" ; const char* mitk::PointSetWriter::XML_SPEC = "specification" ; const char* mitk::PointSetWriter::XML_X = "x" ; const char* mitk::PointSetWriter::XML_Y = "y" ; const char* mitk::PointSetWriter::XML_Z = "z" ; const char* mitk::PointSetWriter::VERSION_STRING = "0.1" ; mitk::PointSetWriter::PointSetWriter() : m_FileName(""), m_FilePrefix(""), m_FilePattern("") { this->SetNumberOfRequiredInputs( 1 ); this->SetNumberOfIndexedOutputs( 1 ); this->SetNthOutput( 0, mitk::PointSet::New().GetPointer() ); m_Indent = 2; m_IndentDepth = 0; m_Success = false; } mitk::PointSetWriter::~PointSetWriter() {} void mitk::PointSetWriter::GenerateData() { m_Success = false; m_IndentDepth = 0; // // Opening the file to write to // if ( m_FileName == "" ) { itkWarningMacro( << "Sorry, filename has not been set!" ); return ; } std::ofstream out( m_FileName.c_str() ); if ( !out.good() ) { itkExceptionMacro(<< "File " << m_FileName << " could not be opened!"); itkWarningMacro( << "Sorry, file " << m_FileName << " could not be opened!" ); out.close(); return ; } 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 ); WriteCharacterData( VERSION_STRING, out ); WriteEndElement( XML_FILE_VERSION, out, false ); // // for each input object write its xml representation to // the stream // for ( unsigned int i = 0 ; i < this->GetNumberOfInputs(); ++i ) { InputType::Pointer pointSet = this->GetInput( i ); assert( pointSet.IsNotNull() ); WriteXML( pointSet.GetPointer(), out ); } WriteEndElement( XML_POINT_SET_FILE, out ); out.imbue(previousLocale); if ( !out.good() ) // some error during output { out.close(); throw std::ios_base::failure("Some error during point set writing."); } out.close(); m_Success = true; m_MimeType = "application/MITK.PointSet"; } void mitk::PointSetWriter::WriteXML( mitk::PointSet* pointSet, std::ofstream& 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 ); WriteCharacterData( ConvertToString( i ).c_str() , out ); 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 ); WriteCharacterData( ConvertToString( it->Index() ).c_str() , out ); WriteEndElement( XML_ID, out, false ); mitk::PointSet::PointType point = it->Value(); WriteStartElement( XML_SPEC, out ); WriteCharacterData( ConvertToString( pointSet->GetSpecificationTypeInfo(it->Index(), i) ).c_str() , out ); WriteEndElement( XML_SPEC, out, false ); WriteStartElement( XML_X, out ); WriteCharacterData( ConvertToString( point[ 0 ] ).c_str(), out ); WriteEndElement( XML_X, out, false ); WriteStartElement( XML_Y, out ); WriteCharacterData( ConvertToString( point[ 1 ] ).c_str(), out ); WriteEndElement( XML_Y, out, false ); WriteStartElement( XML_Z, out ); WriteCharacterData( ConvertToString( point[ 2 ] ).c_str(), out ); WriteEndElement( XML_Z, out, false ); WriteEndElement( XML_POINT, out ); } WriteEndElement( XML_TIME_SERIES, out ); } WriteEndElement( XML_POINT_SET, out ); } void mitk::PointSetWriter::ResizeInputs( const unsigned int& num ) { unsigned int prevNum = this->GetNumberOfInputs(); this->SetNumberOfIndexedInputs( num ); for ( unsigned int i = prevNum; i < num; ++i ) { this->SetNthInput( i, mitk::PointSet::New().GetPointer() ); } } void mitk::PointSetWriter::SetInput( InputType* pointSet ) { this->ProcessObject::SetNthInput( 0, pointSet ); } void mitk::PointSetWriter::SetInput( const unsigned int& id, InputType* pointSet ) { if ( id >= this->GetNumberOfInputs() ) this->ResizeInputs( id + 1 ); this->ProcessObject::SetNthInput( id, pointSet ); } mitk::PointSet* mitk::PointSetWriter::GetInput() { if ( this->GetNumberOfInputs() < 1 ) { return 0; } else { return dynamic_cast ( this->GetInput( 0 ) ); } } mitk::PointSet* mitk::PointSetWriter::GetInput( const unsigned int& num ) { return dynamic_cast ( this->ProcessObject::GetInput( num ) ); } template < typename T> std::string mitk::PointSetWriter::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::PointSetWriter::WriteXMLHeader( std::ofstream &file ) { file << ""; } void mitk::PointSetWriter::WriteStartElement( const char *const tag, std::ofstream &file ) { file << std::endl; WriteIndent( file ); file << '<' << tag << '>'; m_IndentDepth++; } void mitk::PointSetWriter::WriteEndElement( const char *const tag, std::ofstream &file, const bool& indent ) { m_IndentDepth--; if ( indent ) { file << std::endl; WriteIndent( file ); } file << '<' << '/' << tag << '>'; } void mitk::PointSetWriter::WriteCharacterData( const char *const data, std::ofstream &file ) { file << data; } void mitk::PointSetWriter::WriteStartElement( std::string &tag, std::ofstream &file ) { WriteStartElement( tag.c_str(), file ); } void mitk::PointSetWriter::WriteEndElement( std::string &tag, std::ofstream &file, const bool& indent ) { WriteEndElement( tag.c_str(), file, indent ); } void mitk::PointSetWriter::WriteCharacterData( std::string &data, std::ofstream &file ) { WriteCharacterData( data.c_str(), file ); } void mitk::PointSetWriter::WriteIndent( std::ofstream& file ) { std::string spaces( m_IndentDepth * m_Indent, ' ' ); file << spaces.c_str(); } bool mitk::PointSetWriter::GetSuccess() const { return m_Success; } bool mitk::PointSetWriter::CanWriteDataType( DataNode* input ) { if ( input ) { mitk::BaseData* data = input->GetData(); if ( data ) { mitk::PointSet::Pointer pointSet = dynamic_cast( data ); if( pointSet.IsNotNull() ) { //this writer has no "SetDefaultExtension()" - function m_Extension = ".mps"; return true; } } } return false; } void mitk::PointSetWriter::SetInput( DataNode* input ) { if( input && CanWriteDataType( input ) ) this->ProcessObject::SetNthInput( 0, dynamic_cast( input->GetData() ) ); } std::string mitk::PointSetWriter::GetWritenMIMEType() { return m_MimeType; } std::vector mitk::PointSetWriter::GetPossibleFileExtensions() { std::vector possibleFileExtensions; possibleFileExtensions.push_back(".mps"); return possibleFileExtensions; } +std::string mitk::PointSetWriter::GetSupportedBaseData() const +{ + return PointSet::GetStaticNameOfClass(); +} + std::string mitk::PointSetWriter::GetFileExtension() { return m_Extension; } diff --git a/Modules/LegacyIO/mitkPointSetWriter.h b/Modules/LegacyIO/mitkPointSetWriter.h index 85a6307139..35348e20a0 100644 --- a/Modules/LegacyIO/mitkPointSetWriter.h +++ b/Modules/LegacyIO/mitkPointSetWriter.h @@ -1,271 +1,273 @@ /*=================================================================== 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_POINT_SET_WRITER__H_ #define _MITK_POINT_SET_WRITER__H_ #include #include #include #include namespace mitk { /** * @brief XML-based writer for mitk::PointSets * * XML-based writer for mitk::PointSets. Multiple PointSets can be written in * a single XML file by simply setting multiple inputs to the filter. * Writing of multiple XML files according to a given filename pattern is not * yet supported. * @ingroup PSIO * @ingroup Process * * @deprecatedSince{2014_03} Use mitk::IOUtils or mitk::FileReaderRegistry instead. */ class MitkLegacyIO_EXPORT PointSetWriter : public mitk::FileWriter { public: mitkClassMacro( PointSetWriter, mitk::FileWriter ); mitkWriterMacro; itkFactorylessNewMacro(Self) itkCloneMacro(Self) typedef mitk::PointSet InputType; typedef InputType::Pointer InputTypePointer; /** * Sets the filename of the file to write. * @param FileName 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 SetInput( InputType* input ); /** * Sets the n'th input object for the filter. If num is * larger than GetNumberOfInputs() the number of inputs is * resized appropriately. * @param input the n'th input for the filter. */ void SetInput( const unsigned int& num, InputType* input); /** * @returns the 0'th input object of the filter. */ PointSet* GetInput(); /** * @param num the index of the desired output object. * @returns the n'th input object of the filter. */ PointSet* GetInput( const unsigned int& num ); /** * @brief Return the possible file extensions for the data type associated with the writer */ virtual std::vector GetPossibleFileExtensions(); + virtual std::string GetSupportedBaseData() const; + /** * @brief Return the extension to be added to the filename. */ virtual std::string GetFileExtension(); /** * @brief Check if the Writer can write the Content of the */ virtual bool CanWriteDataType( DataNode* ); /** * @brief Return the MimeType of the saved File. */ virtual std::string GetWritenMIMEType(); using mitk::FileWriter::SetInput; /** * @brief Set the DataTreenode as Input. Important: The Writer always have a SetInput-Function. */ virtual void SetInput( DataNode* ); /** * @returns whether the last write attempt was successful or not. */ bool GetSuccess() const; protected: /** * Constructor. */ PointSetWriter(); /** * Virtual destructor. */ virtual ~PointSetWriter(); /** * Writes the XML file */ virtual void GenerateData(); /** * Resizes the number of inputs of the writer. * The inputs are initialized by empty PointSets * @param num the new number of inputs */ virtual void ResizeInputs( const unsigned int& num ); /** * Converts an arbitrary type to a string. The type has to * support the << operator. This works fine at least for integral * data types as float, int, long etc. * @param value the value to convert * @returns the string representation of value */ template < typename T> std::string ConvertToString( T value ); /** * Writes an XML representation of the given point set to * an outstream. The XML-Header an root node is not included! * @param pointSet the point set to be converted to xml * @param out the stream to write to. */ void WriteXML( mitk::PointSet* pointSet, std::ofstream& out ); /** * Writes an standard xml header to the given stream. * @param file the stream in which the header is written. */ void WriteXMLHeader( std::ofstream &file ); /** Write a start element tag */ void WriteStartElement( const char *const tag, std::ofstream &file ); /** * Write an end element tag * End-Elements following character data should pass indent = false. */ void WriteEndElement( const char *const tag, std::ofstream &file, const bool& indent = true ); /** Write character data inside a tag. */ void WriteCharacterData( const char *const data, std::ofstream &file ); /** Write a start element tag */ void WriteStartElement( std::string &tag, std::ofstream &file ); /** Write an end element tag */ void WriteEndElement( std::string &tag, std::ofstream &file, const bool& indent = true ); /** Write character data inside a tag. */ void WriteCharacterData( std::string &data, std::ofstream &file ); /** Writes empty spaces to the stream according to m_IndentDepth and m_Indent */ void WriteIndent( std::ofstream& file ); std::string m_FileName; std::string m_FilePrefix; std::string m_FilePattern; std::string m_Extension; std::string m_MimeType; unsigned int m_IndentDepth; unsigned int m_Indent; bool m_Success; public: static const char* XML_POINT_SET; static const char* XML_TIME_SERIES; static const char* XML_TIME_SERIES_ID; static const char* XML_POINT_SET_FILE; static const char* XML_FILE_VERSION; static const char* XML_POINT; static const char* XML_SPEC; static const char* XML_ID; static const char* XML_X; static const char* XML_Y; static const char* XML_Z; static const char* VERSION_STRING; }; } #endif diff --git a/Modules/LegacyIO/mitkSurfaceVtkWriter.h b/Modules/LegacyIO/mitkSurfaceVtkWriter.h index 1d49c33a8e..06205db9e5 100644 --- a/Modules/LegacyIO/mitkSurfaceVtkWriter.h +++ b/Modules/LegacyIO/mitkSurfaceVtkWriter.h @@ -1,207 +1,210 @@ /*=================================================================== 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_WRITER__H_ #define _MITK_SURFACE_VTK_WRITER__H_ #include #include #include #include #include #include #include #include #include #include class vtkTransformPolyDataFilter; namespace mitk { /** * @brief VTK-based writer for mitk::Surface * * The mitk::Surface is written using the VTK-writer-type provided as the * template argument. 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 * * @deprecatedSince{2014_03} Use mitk::IOUtils or mitk::FileReaderRegistry instead. */ template class DEPRECATED() MitkLegacyIO_EXPORT SurfaceVtkWriter : public mitk::FileWriter { public: mitkClassMacro( SurfaceVtkWriter, mitk::FileWriter ); itkFactorylessNewMacro(Self) itkCloneMacro(Self) mitkWriterMacro; typedef VTKWRITER VtkWriterType; /** * 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 ); /** * \brief Explicitly set the extension to be added to the filename. * @param _arg to be added to the filename, including a "." * (e.g., ".vtk"). * * Partial template specialization is used for some vtk-writer types * to set a default extension. */ itkSetStringMacro( Extension ); /** * \brief Get the extension to be added to the filename. * @returns the extension to be added to the filename (e.g., * ".vtk"). */ itkGetStringMacro( Extension ); /** * \brief Set the extension to be added to the filename to the default * * Partial template specialization is used for some vtk-writer types * to define the default extension. */ void SetDefaultExtension(); /** * @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 SetInput( mitk::Surface* input ); /** * @returns the 0'th input object of the filter. */ const mitk::Surface* GetInput(); /** * @brief Return the extension to be added to the filename. */ virtual std::string GetFileExtension(); /** * @brief Check if the Writer can write the Content of the DataTreenode. */ virtual bool CanWriteDataType( DataNode* ); /** * @brief Return the MimeType of the saved File. */ virtual std::string GetWritenMIMEType(); using Superclass::SetInput; /** * @brief Set the DataTreenode as Input. Important: The Writer always have a SetInput-Function. */ virtual void SetInput( DataNode* ); VtkWriterType* GetVtkWriter() { return m_VtkWriter; } /** * @brief Return the possible file extensions for the data type associated with the writer */ virtual std::vector GetPossibleFileExtensions(); + virtual std::string GetSupportedBaseData() const + { return Surface::GetStaticNameOfClass(); } + protected: /** * Constructor. */ SurfaceVtkWriter(); /** * Virtual destructor. */ virtual ~SurfaceVtkWriter(); virtual void GenerateData(); void ExecuteWrite( VtkWriterType* vtkWriter ); std::string m_FileName; std::string m_FilePrefix; std::string m_FilePattern; std::string m_Extension; std::string m_MimeType; vtkSmartPointer m_VtkWriter; bool m_WriterWriteHasReturnValue; }; #ifndef MitkLegacyIO_EXPORTS extern template class SurfaceVtkWriter; extern template class SurfaceVtkWriter; extern template class SurfaceVtkWriter; #endif } #endif //_MITK_SURFACE_VTK_WRITER__H_ diff --git a/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.cpp b/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.cpp index ad636be211..80e8209f65 100644 --- a/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.cpp +++ b/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.cpp @@ -1,303 +1,308 @@ /*=================================================================== 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 "mitkPlanarFigureWriter.h" #include "mitkBasePropertySerializer.h" #include "mitkPlaneGeometry.h" #include mitk::PlanarFigureWriter::PlanarFigureWriter() : m_FileName(""), m_FilePrefix(""), m_FilePattern(""), m_Extension(".pf"), m_MimeType("application/MITK.PlanarFigure"), m_Success(false) { this->SetNumberOfRequiredInputs( 1 ); this->SetNumberOfIndexedOutputs( 0 ); //this->SetNthOutput( 0, mitk::PlanarFigure::New().GetPointer() ); m_CanWriteToMemory = true; } mitk::PlanarFigureWriter::~PlanarFigureWriter() {} void mitk::PlanarFigureWriter::GenerateData() { m_Success = false; if (!m_WriteToMemory && m_FileName.empty()) { MITK_ERROR << "Could not write planar figures. File name is invalid"; throw std::invalid_argument("file name is empty"); } TiXmlDocument document; TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" ); // TODO what to write here? encoding? etc.... document.LinkEndChild( decl ); TiXmlElement* version = new TiXmlElement("Version"); version->SetAttribute("Writer", __FILE__ ); version->SetAttribute("CVSRevision", "$Revision: 17055 $" ); version->SetAttribute("FileVersion", 1 ); document.LinkEndChild(version); /* create xml element for each input */ for ( unsigned int i = 0 ; i < this->GetNumberOfInputs(); ++i ) { // Create root element for this PlanarFigure InputType::Pointer pf = this->GetInput( i ); if (pf.IsNull()) continue; TiXmlElement* pfElement = new TiXmlElement("PlanarFigure"); pfElement->SetAttribute("type", pf->GetNameOfClass()); document.LinkEndChild(pfElement); if ( pf->GetNumberOfControlPoints() == 0 ) continue; //PlanarFigure::VertexContainerType* vertices = pf->GetControlPoints(); //if (vertices == NULL) // continue; // Serialize property list of PlanarFigure mitk::PropertyList::Pointer propertyList = pf->GetPropertyList(); mitk::PropertyList::PropertyMap::const_iterator it; for ( it = propertyList->GetMap()->begin(); it != propertyList->GetMap()->end(); ++it ) { // Create seralizer for this property const mitk::BaseProperty* prop = it->second; std::string serializerName = std::string( prop->GetNameOfClass() ) + "Serializer"; std::list< itk::LightObject::Pointer > allSerializers = itk::ObjectFactoryBase::CreateAllInstance( serializerName.c_str() ); if ( allSerializers.size() != 1 ) { // No or too many serializer(s) found, skip this property continue; } mitk::BasePropertySerializer* serializer = dynamic_cast< mitk::BasePropertySerializer* >( allSerializers.begin()->GetPointer() ); if ( serializer == NULL ) { // Serializer not valid; skip this property } TiXmlElement* keyElement = new TiXmlElement( "property" ); keyElement->SetAttribute( "key", it->first ); keyElement->SetAttribute( "type", prop->GetNameOfClass() ); serializer->SetProperty( prop ); TiXmlElement* valueElement = NULL; try { valueElement = serializer->Serialize(); } catch (...) { } if ( valueElement == NULL ) { // Serialization failed; skip this property continue; } // Add value to property element keyElement->LinkEndChild( valueElement ); // Append serialized property to property list pfElement->LinkEndChild( keyElement ); } // Serialize control points of PlanarFigure TiXmlElement* controlPointsElement = new TiXmlElement("ControlPoints"); pfElement->LinkEndChild(controlPointsElement); for (unsigned int i = 0; i < pf->GetNumberOfControlPoints(); i++) { TiXmlElement* vElement = new TiXmlElement("Vertex"); vElement->SetAttribute("id", i); vElement->SetDoubleAttribute("x", pf->GetControlPoint(i)[0]); vElement->SetDoubleAttribute("y", pf->GetControlPoint(i)[1]); controlPointsElement->LinkEndChild(vElement); } TiXmlElement* geoElement = new TiXmlElement("Geometry"); const PlaneGeometry* planeGeo = dynamic_cast(pf->GetPlaneGeometry()); if (planeGeo != NULL) { // Write parameters of IndexToWorldTransform of the PlaneGeometry typedef mitk::Geometry3D::TransformType TransformType; const TransformType* affineGeometry = planeGeo->GetIndexToWorldTransform(); const TransformType::ParametersType& parameters = affineGeometry->GetParameters(); TiXmlElement* vElement = new TiXmlElement( "transformParam" ); for ( unsigned int i = 0; i < affineGeometry->GetNumberOfParameters(); ++i ) { std::stringstream paramName; paramName << "param" << i; vElement->SetDoubleAttribute( paramName.str().c_str(), parameters.GetElement( i ) ); } geoElement->LinkEndChild( vElement ); // Write bounds of the PlaneGeometry typedef mitk::Geometry3D::BoundsArrayType BoundsArrayType; const BoundsArrayType& bounds = planeGeo->GetBounds(); vElement = new TiXmlElement( "boundsParam" ); for ( unsigned int i = 0; i < 6; ++i ) { std::stringstream boundName; boundName << "bound" << i; vElement->SetDoubleAttribute( boundName.str().c_str(), bounds.GetElement( i ) ); } geoElement->LinkEndChild( vElement ); // Write spacing and origin of the PlaneGeometry Vector3D spacing = planeGeo->GetSpacing(); Point3D origin = planeGeo->GetOrigin(); geoElement->LinkEndChild(this->CreateXMLVectorElement("Spacing", spacing)); geoElement->LinkEndChild(this->CreateXMLVectorElement("Origin", origin)); pfElement->LinkEndChild(geoElement); } } if(m_WriteToMemory) { // Declare a printer TiXmlPrinter printer; // attach it to the document you want to convert in to a std::string document.Accept(&printer); // Create memory buffer and print tinyxmldocument there... m_MemoryBufferSize = printer.Size() + 1; m_MemoryBuffer = new char[m_MemoryBufferSize]; strcpy(m_MemoryBuffer,printer.CStr()); } else { if (document.SaveFile( m_FileName) == false) { MITK_ERROR << "Could not write planar figures to " << m_FileName << "\nTinyXML reports '" << document.ErrorDesc() << "'"; throw std::ios_base::failure("Error during writing of planar figure xml file."); } } m_Success = true; } void mitk::PlanarFigureWriter::ReleaseMemory() { if(m_MemoryBuffer != NULL) { delete [] m_MemoryBuffer; } } TiXmlElement* mitk::PlanarFigureWriter::CreateXMLVectorElement(const char* name, itk::FixedArray v) { TiXmlElement* vElement = new TiXmlElement(name); vElement->SetDoubleAttribute("x", v.GetElement(0)); vElement->SetDoubleAttribute("y", v.GetElement(1)); vElement->SetDoubleAttribute("z", v.GetElement(2)); return vElement; } void mitk::PlanarFigureWriter::ResizeInputs( const unsigned int& num ) { //unsigned int prevNum = this->GetNumberOfInputs(); this->SetNumberOfIndexedInputs( num ); //for ( unsigned int i = prevNum; i < num; ++i ) //{ // this->SetNthInput( i, mitk::PlanarFigure::New().GetPointer() ); //} } void mitk::PlanarFigureWriter::SetInput( InputType* PlanarFigure ) { this->ProcessObject::SetNthInput( 0, PlanarFigure ); } void mitk::PlanarFigureWriter::SetInput( const unsigned int& id, InputType* PlanarFigure ) { if ( id >= this->GetNumberOfInputs() ) this->ResizeInputs( id + 1 ); this->ProcessObject::SetNthInput( id, PlanarFigure ); } mitk::PlanarFigure* mitk::PlanarFigureWriter::GetInput() { if ( this->GetNumberOfInputs() < 1 ) return NULL; else return dynamic_cast ( this->GetInput( 0 ) ); } mitk::PlanarFigure* mitk::PlanarFigureWriter::GetInput( const unsigned int& num ) { return dynamic_cast ( this->ProcessObject::GetInput( num ) ); } bool mitk::PlanarFigureWriter::CanWriteDataType( DataNode* input ) { if ( input == NULL ) return false; mitk::BaseData* data = input->GetData(); if ( data == NULL) return false; mitk::PlanarFigure::Pointer PlanarFigure = dynamic_cast( data ); if( PlanarFigure.IsNull() ) return false; // add code for special subclasses here return true; } void mitk::PlanarFigureWriter::SetInput( DataNode* input ) { if (this->CanWriteDataType(input)) this->ProcessObject::SetNthInput( 0, dynamic_cast( input->GetData() ) ); } +std::string mitk::PlanarFigureWriter::GetSupportedBaseData() const +{ + return PlanarFigure::GetStaticNameOfClass(); +} + std::string mitk::PlanarFigureWriter::GetWritenMIMEType() { return m_MimeType; } std::vector mitk::PlanarFigureWriter::GetPossibleFileExtensions() { std::vector possibleFileExtensions; possibleFileExtensions.push_back(m_Extension); return possibleFileExtensions; } std::string mitk::PlanarFigureWriter::GetFileExtension() { return m_Extension; } diff --git a/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.h b/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.h index 729a3ad4f1..9c7546e270 100644 --- a/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.h +++ b/Modules/PlanarFigure/IO/mitkPlanarFigureWriter.h @@ -1,206 +1,208 @@ /*=================================================================== 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_PlanarFigure_WRITER__H_ #define _MITK_PlanarFigure_WRITER__H_ #include #include #include #include class TiXmlElement; namespace mitk { /** * @brief XML-based writer for mitk::PlanarFigures * * XML-based writer for mitk::PlanarFigures. * @ingroup Process */ class MitkPlanarFigure_EXPORT PlanarFigureWriter : public mitk::FileWriterWithInformation { public: mitkClassMacro( PlanarFigureWriter, mitk::FileWriter ); mitkWriterMacro; itkFactorylessNewMacro(Self) itkCloneMacro(Self) typedef mitk::PlanarFigure InputType; typedef InputType::Pointer InputTypePointer; /** * Sets the filename of the file to write. * @param FileName 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 ); using Superclass::SetInput; /** * Sets the 0'th input object for the filter. * @param input the first input for the filter. */ void SetInput( InputType* input ); /** * Sets the n'th input object for the filter. If num is * larger than GetNumberOfInputs() the number of inputs is * resized appropriately. * @param input the n'th input for the filter. */ void SetInput( const unsigned int& num, InputType* input); /** * @returns the 0'th input object of the filter. */ PlanarFigure* GetInput(); /** * @param num the index of the desired output object. * @returns the n'th input object of the filter. */ PlanarFigure* GetInput( const unsigned int& num ); /** * @brief Return the possible file extensions for the data type associated with the writer */ virtual std::vector GetPossibleFileExtensions(); /** * @brief Return the extension to be added to the filename. */ virtual std::string GetFileExtension(); /** * @brief Check if the Writer can write the Content of the */ virtual bool CanWriteDataType( DataNode* ); /** * @brief Return the MimeType of the saved File. */ virtual std::string GetWritenMIMEType(); /** * @brief Set the DataTreenode as Input. Important: The Writer always have a SetInput-Function. */ virtual void SetInput( DataNode* ); + virtual std::string GetSupportedBaseData() const; + /** * @returns whether the last write attempt was successful or not. */ itkGetConstMacro(Success, bool); virtual const char * GetDefaultFilename() { return "PlanarFigure.pf"; } virtual const char * GetFileDialogPattern() { return "Planar Figure Files (*.pf)"; } virtual const char * GetDefaultExtension() { return ".pf"; } virtual bool CanWriteBaseDataType(BaseData::Pointer data) { return dynamic_cast( data.GetPointer() ); } virtual void DoWrite(BaseData::Pointer data) { if (CanWriteBaseDataType(data)) { this->SetInput(dynamic_cast(data.GetPointer())); this->Update(); } } /** @brief CAUTION: It's up to the user to call this function to release the memory buffer after use in case the file writer has written to its memory array. See mitkFileWriter base class. */ virtual void ReleaseMemory(); protected: /** * Constructor. */ PlanarFigureWriter(); /** * Virtual destructor. */ virtual ~PlanarFigureWriter(); /** * Writes the a .pf file in xml format that contains all input planar figures */ virtual void GenerateData(); /** * Resizes the number of inputs of the writer. * The inputs are initialized by empty PlanarFigures * @param num the new number of inputs */ virtual void ResizeInputs( const unsigned int& num ); /**Documentation * \brief creates a TinyXML element that contains x, y, and z values * * \param[in] name the name of the XML element * \param[in] v the vector or point that contains the x, y and z values * \return returns a TiXmlElement named name and three attributes x, y and z. */ TiXmlElement* CreateXMLVectorElement(const char* name, itk::FixedArray v); std::string m_FileName; std::string m_FilePrefix; std::string m_FilePattern; std::string m_Extension; std::string m_MimeType; bool m_Success; }; } #endif