diff --git a/Core/Code/IO/mitkImageWriter.cpp b/Core/Code/IO/mitkImageWriter.cpp index 64602eacbc..ba4becb41a 100644 --- a/Core/Code/IO/mitkImageWriter.cpp +++ b/Core/Code/IO/mitkImageWriter.cpp @@ -1,297 +1,297 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkImageWriter.h" #include "mitkItkPictureWrite.h" #include "mitkImage.h" #include "mitkImageTimeSelector.h" #include "mitkPicFileWriter.h" #include "mitkImageAccessByItk.h" #include #include mitk::ImageWriter::ImageWriter() { this->SetNumberOfRequiredInputs( 1 ); m_MimeType = ""; SetDefaultExtension(); } mitk::ImageWriter::~ImageWriter() { } void mitk::ImageWriter::SetDefaultExtension() { m_Extension = ".mhd"; } #include #if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) #include #include static void writeVti(const char * filename, mitk::Image* image, int t=0) { vtkXMLImageDataWriter * vtkwriter = vtkXMLImageDataWriter::New(); vtkwriter->SetFileName( filename ); vtkwriter->SetInput(image->GetVtkImageData(t)); vtkwriter->Write(); vtkwriter->Delete(); } #endif void mitk::ImageWriter::WriteByITK(mitk::Image* image, const std::string& fileName) { // 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) { AccessByItk_1( image, _mitkItkPictureWrite, fileName ); 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 spacing = image->GetGeometry()->GetSpacing(); mitk::Point3D origin = image->GetGeometry()->GetOrigin(); 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->SetPixelTypeInfo( *(pixelType.GetTypeId()) ); if(pixelType.GetNumberOfComponents() > 1) imageIO->SetNumberOfComponents(pixelType.GetNumberOfComponents()); itk::ImageIORegion ioRegion( dimension ); for(unsigned int i=0; iSetDimensions(i,dimensions[i]); imageIO->SetSpacing(i,spacing[i]); imageIO->SetOrigin(i,origin[i]); mitk::Vector3D direction; direction.Set_vnl_vector(image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix().get_column(i)); 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) ); } imageIO->SetIORegion(ioRegion); imageIO->SetFileName(fileName); const void * data = image->GetData(); imageIO->Write(data); } void mitk::ImageWriter::GenerateData() { 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()); mitk::Image::Pointer input = const_cast(this->GetInput()); #if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) bool vti = (m_Extension.find(".vti") != std::string::npos); #endif if ( m_Extension.find(".pic") == 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) { ::itk::OStringStream filename; timeSelector->SetTimeNr(t); timeSelector->Update(); if(input->GetTimeSlicedGeometry()->IsValidTime(t)) { const mitk::TimeBounds& timebounds = input->GetTimeSlicedGeometry()->GetGeometry3D(t)->GetTimeBounds(); filename << m_FileName.c_str() << "_S" << std::setprecision(0) << timebounds[0] << "_E" << std::setprecision(0) << timebounds[1] << "_T" << t << m_Extension; } else { itkWarningMacro(<<"Error on write: TimeSlicedGeometry invalid of image " << filename << "."); filename << m_FileName.c_str() << "_T" << t << m_Extension; } #if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) if ( vti ) { writeVti(filename.str().c_str(), input, t); } else #endif { WriteByITK(input, filename.str()); } } } #if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) else if ( vti ) { ::itk::OStringStream filename; filename << m_FileName.c_str() << m_Extension; writeVti(filename.str().c_str(), input); } #endif else { ::itk::OStringStream filename; filename << m_FileName.c_str() << m_Extension; WriteByITK(input, filename.str()); } } else { 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 ::itk::OStringStream filename; filename << m_FileName.c_str() << m_Extension; picWriter->SetFileName( filename.str().c_str() ); } else { picWriter->SetFileName( m_FileName.c_str() ); } - picWriter->SetInput( input ); + picWriter->SetInputImage( input ); picWriter->Write(); } m_MimeType = "application/MITK.Pic"; } bool mitk::ImageWriter::CanWriteDataType( DataNode* input ) { if ( input ) { mitk::BaseData* data = input->GetData(); if ( data ) { mitk::Image::Pointer image = dynamic_cast( data ); if( image.IsNotNull() ) { //"SetDefaultExtension()" set m_Extension to ".mhd" ????? m_Extension = ".pic"; return true; } } } 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(".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(".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(".png"); possibleFileExtensions.push_back(".tif"); possibleFileExtensions.push_back(".jpg"); return possibleFileExtensions; } 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 ) ); } } diff --git a/Core/Code/IO/mitkPicFileWriter.cpp b/Core/Code/IO/mitkPicFileWriter.cpp index 3a8e58b878..a227112b5b 100644 --- a/Core/Code/IO/mitkPicFileWriter.cpp +++ b/Core/Code/IO/mitkPicFileWriter.cpp @@ -1,297 +1,297 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #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." ); } mitkIpPicDescriptor * picImage = input->GetPic(); 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::SetInput( Image* image ) +void mitk::PicFileWriter::SetInputImage( Image* image ) { this->ProcessObject::SetNthInput( 0, image ); } const mitk::Image* mitk::PicFileWriter::GetInput() { if ( this->GetNumberOfInputs() < 1 ) { 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; } diff --git a/Core/Code/IO/mitkPicFileWriter.h b/Core/Code/IO/mitkPicFileWriter.h index 2b6bf7fcbc..b4e4bbb709 100644 --- a/Core/Code/IO/mitkPicFileWriter.h +++ b/Core/Code/IO/mitkPicFileWriter.h @@ -1,117 +1,117 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_PIC_FILE_WRITER__H_ #define _MITK_PIC_FILE_WRITER__H_ #include #include namespace mitk { class Image; /** * @brief Writer for mitk::Image * @ingroup IO */ class MITK_CORE_EXPORT PicFileWriter : public mitk::FileWriter { public: mitkClassMacro( PicFileWriter, mitk::FileWriter ); itkNewMacro( 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 SetInput( mitk::Image* input ); + 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(); 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_