1 /*=========================================================================
3 * Copyright RTK Consortium
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 *=========================================================================*/
19 #include "rtkImagXImageIO.h"
20 #include "rtkImagXXMLFileReader.h"
22 // itk include (for itkReadRawBytesAfterSwappingMacro)
23 #include <itkRawImageIO.h>
24 #include <itksys/SystemTools.hxx>
25 #include <itkMetaDataObject.h>
26 #include <itkMatrix.h>
28 //--------------------------------------------------------------------
29 // Read Image Information
30 void rtk::ImagXImageIO::ReadImageInformation()
32 rtk::ImagXXMLFileReader::Pointer xmlReader;
34 xmlReader = rtk::ImagXXMLFileReader::New();
35 xmlReader->SetFilename(m_FileName);
36 xmlReader->GenerateOutputInformation();
38 itk::MetaDataDictionary &dic = *(xmlReader->GetOutputObject() );
40 typedef itk::MetaDataObject< double > MetaDataDoubleType;
41 typedef itk::MetaDataObject< std::string > MetaDataStringType;
42 typedef itk::MetaDataObject< int > MetaDataIntType;
44 std::string pixelType = dynamic_cast<MetaDataStringType*>(dic["pixelFormat"].GetPointer() )->GetMetaDataObjectValue();
45 if(pixelType=="Type_uint8")
46 SetComponentType(itk::ImageIOBase::UCHAR);
47 if(pixelType=="Type_sint8")
48 SetComponentType(itk::ImageIOBase::CHAR);
49 if(pixelType=="Type_uint16")
50 SetComponentType(itk::ImageIOBase::USHORT);
51 if(pixelType=="Type_sint16")
52 SetComponentType(itk::ImageIOBase::SHORT);
53 if(pixelType=="Type_uint32")
54 SetComponentType(itk::ImageIOBase::UINT);
55 if(pixelType=="Type_sint32")
56 SetComponentType(itk::ImageIOBase::INT);
57 if(pixelType=="Type_float")
58 SetComponentType(itk::ImageIOBase::FLOAT);
60 if( dic["dimensions"].GetPointer() == NULL )
61 SetNumberOfDimensions(3);
63 SetNumberOfDimensions( ( dynamic_cast<MetaDataIntType *>(dic["dimensions"].GetPointer() )->GetMetaDataObjectValue() ) );
65 SetDimensions(0, dynamic_cast<MetaDataIntType *>(dic["x"].GetPointer() )->GetMetaDataObjectValue() );
66 SetSpacing(0, dynamic_cast<MetaDataDoubleType *>(dic["spacing_x"].GetPointer() )->GetMetaDataObjectValue() );
67 if(GetNumberOfDimensions()>1)
69 SetDimensions(1, dynamic_cast<MetaDataIntType *>(dic["y"].GetPointer() )->GetMetaDataObjectValue() );
70 SetSpacing(1, dynamic_cast<MetaDataDoubleType *>(dic["spacing_y"].GetPointer() )->GetMetaDataObjectValue() );
72 if(GetNumberOfDimensions()>2)
74 SetDimensions(2, dynamic_cast<MetaDataIntType *>(dic["z"].GetPointer() )->GetMetaDataObjectValue() );
75 SetSpacing(2, dynamic_cast<MetaDataDoubleType *>(dic["spacing_z"].GetPointer() )->GetMetaDataObjectValue() );
76 if(GetSpacing(2) == 0)
80 itk::Matrix<double, 4, 4> matrix;
81 if(dic["matrixTransform"].GetPointer() == NULL)
85 std::istringstream iss(
86 dynamic_cast<MetaDataStringType*>(dic["matrixTransform"].GetPointer() )->GetMetaDataObjectValue() );
87 for(unsigned int j=0; j<4; j++)
88 for(unsigned int i=0; i<4; i++)
90 matrix /= matrix[3][3];
93 std::vector<double> direction;
94 for(unsigned int i=0; i<GetNumberOfDimensions(); i++)
97 for(unsigned int j=0; j<GetNumberOfDimensions(); j++)
98 direction.push_back(matrix[i][j]);
99 SetDirection(i, direction);
100 SetOrigin(i, matrix[i][3]);
103 if(std::string("LSB") == dynamic_cast<MetaDataStringType*>(dic["byteOrder"].GetPointer() )->GetMetaDataObjectValue() )
104 this->SetByteOrder(LittleEndian);
106 this->SetByteOrder(BigEndian);
108 // Prepare raw file name
109 m_RawFileName = itksys::SystemTools::GetFilenamePath(m_FileName);
110 if(m_RawFileName != "")
111 m_RawFileName += std::string("/");
112 m_RawFileName += dynamic_cast<MetaDataStringType*>(dic["rawFile"].GetPointer() )->GetMetaDataObjectValue();
115 //--------------------------------------------------------------------
116 // Read Image Information
117 bool rtk::ImagXImageIO::CanReadFile(const char* FileNameToRead)
119 std::string ext = itksys::SystemTools::GetFilenameLastExtension(FileNameToRead);
121 if( ext!=std::string(".xml") )
124 std::ifstream is(FileNameToRead);
128 // If the XML file has "<image name=" at the beginning of the first or second
129 // line, we assume this is an ImagX file
132 std::getline(is, line);
133 if(line.substr(0, 12) == std::string("<image name=") )
136 std::getline(is, line);
137 if(line.substr(0, 12) == std::string("<image name=") )
143 //--------------------------------------------------------------------
144 // Read Image Content
145 void rtk::ImagXImageIO::Read(void * buffer)
147 // Adapted from itkRawImageIO
148 std::ifstream is(m_RawFileName.c_str(), std::ios::binary);
151 itkExceptionMacro(<<"Could not open file " << m_RawFileName);
153 unsigned long numberOfBytesToBeRead = GetComponentSize();
154 for(unsigned int i=0; i<GetNumberOfDimensions(); i++) numberOfBytesToBeRead *= GetDimensions(i);
156 if(!this->ReadBufferAsBinary(is, buffer, numberOfBytesToBeRead) ) {
157 itkExceptionMacro(<<"Read failed: Wanted "
158 << numberOfBytesToBeRead
159 << " bytes, but read "
160 << is.gcount() << " bytes.");
162 itkDebugMacro(<< "Reading Done");
164 // Adapted from itkRawImageIO
167 // Swap bytes if necessary
168 if itkReadRawBytesAfterSwappingMacro( unsigned short, USHORT )
169 else if itkReadRawBytesAfterSwappingMacro( short, SHORT )
170 else if itkReadRawBytesAfterSwappingMacro( char, CHAR )
171 else if itkReadRawBytesAfterSwappingMacro( unsigned char, UCHAR )
172 else if itkReadRawBytesAfterSwappingMacro( unsigned int, UINT )
173 else if itkReadRawBytesAfterSwappingMacro( int, INT )
174 else if itkReadRawBytesAfterSwappingMacro( unsigned int, ULONG )
175 else if itkReadRawBytesAfterSwappingMacro( int, LONG )
176 else if itkReadRawBytesAfterSwappingMacro( float, FLOAT )
177 else if itkReadRawBytesAfterSwappingMacro( double, DOUBLE );
181 //--------------------------------------------------------------------
182 // Write Image Information
183 void rtk::ImagXImageIO::WriteImageInformation( bool itkNotUsed(keepOfStream) )
187 //--------------------------------------------------------------------
188 // Write Image Information
189 bool rtk::ImagXImageIO::CanWriteFile( const char* itkNotUsed(FileNameToWrite) )
194 //--------------------------------------------------------------------
196 void rtk::ImagXImageIO::Write( const void * itkNotUsed(buffer) )