]> Creatis software - clitk.git/blob - common/rtkHisImageIO.cxx
Add define to avoid vtk warning on mac
[clitk.git] / common / rtkHisImageIO.cxx
1 /*=========================================================================
2  *
3  *  Copyright RTK Consortium
4  *
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
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
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.
16  *
17  *=========================================================================*/
18
19 #define HEADER_INFO_SIZE 68
20
21 // Based on a true story by the Nederlands Kanker Instituut (AVS_HEIMANN.CPP
22 // from the 20090608)
23
24 // Includes
25 #include <fstream>
26 #include "rtkHisImageIO.h"
27
28 //--------------------------------------------------------------------
29 // Read Image Information
30 void rtk::HisImageIO::ReadImageInformation()
31 {
32   // open file
33   std::ifstream file(m_FileName.c_str(), std::ios::in | std::ios::binary);
34
35   if ( file.fail() )
36     itkGenericExceptionMacro(<< "Could not open file (for reading): "
37                              << m_FileName);
38
39   // read header
40   char header[HEADER_INFO_SIZE];
41   file.read(header, HEADER_INFO_SIZE);
42
43   if (header[0]!=0 || header[1]!=112 || header[2]!=68 || header[3]!=0) {
44     itkExceptionMacro(<< "rtk::HisImageIO::ReadImageInformation: file "
45                       << m_FileName
46                       << " not in Heimann HIS format version 100");
47     return;
48     }
49
50   int nrframes, type, ulx, uly, brx, bry;
51   m_HeaderSize  = header[10] + (header[11]<<8);
52   ulx           = header[12] + (header[13]<<8);
53   uly           = header[14] + (header[15]<<8);
54   brx           = header[16] + (header[17]<<8);
55   bry           = header[18] + (header[19]<<8);
56   nrframes      = header[20] + (header[21]<<8);
57   type          = header[32] + (header[34]<<8);
58
59   switch(type)
60     {
61     case  4:
62       SetComponentType(itk::ImageIOBase::USHORT);
63       break;
64 //    case  8: SetComponentType(itk::ImageIOBase::INT);   break;
65 //    case 16: SetComponentType(itk::ImageIOBase::FLOAT); break;
66 //    case 32: SetComponentType(itk::ImageIOBase::INT);   break;
67     default:
68       SetComponentType(itk::ImageIOBase::USHORT);
69       break;
70     }
71
72   switch(nrframes)
73     {
74     case 1:
75       SetNumberOfDimensions(2);
76       break;
77     default:
78       SetNumberOfDimensions(3);
79       break;
80     }
81
82   SetDimensions(0, bry-uly+1);
83   SetDimensions(1, brx-ulx+1);
84   if (nrframes>1)
85     SetDimensions(2, nrframes);
86
87   SetSpacing(0, 409.6/GetDimensions(0) );
88   SetSpacing(1, 409.6/GetDimensions(1) );
89
90   SetOrigin(0, -0.5*(GetDimensions(0)-1)*GetSpacing(0) );
91   SetOrigin(1, -0.5*(GetDimensions(1)-1)*GetSpacing(1) );
92 } ////
93
94 //--------------------------------------------------------------------
95 // Read Image Information
96 bool rtk::HisImageIO::CanReadFile(const char* FileNameToRead)
97 {
98   std::string                  filename(FileNameToRead);
99   const std::string::size_type it = filename.find_last_of( "." );
100   std::string                  fileExt( filename, it+1, filename.length() );
101
102   if (fileExt != std::string("his") )
103     return false;
104   return true;
105 } ////
106
107 //--------------------------------------------------------------------
108 // Read Image Content
109 void rtk::HisImageIO::Read(void * buffer)
110 {
111   // open file
112   std::ifstream file(m_FileName.c_str(), std::ios::in | std::ios::binary);
113
114   if ( file.fail() )
115     itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);
116
117   file.seekg(m_HeaderSize+HEADER_INFO_SIZE, std::ios::beg);
118   if ( file.fail() )
119     itkExceptionMacro(<<"File seek failed (His Read)");
120
121   file.read( (char*)buffer, GetImageSizeInBytes() );
122   if ( file.fail() )
123     itkExceptionMacro(<<"Read failed: Wanted "
124                       << GetImageSizeInBytes()
125                       << " bytes, but read "
126                       << file.gcount() << " bytes. The current state is: "
127                       << file.rdstate() );
128 }
129
130 //--------------------------------------------------------------------
131 bool rtk::HisImageIO::CanWriteFile(const char* FileNameToWrite)
132 {
133   return CanReadFile(FileNameToWrite);
134 }
135
136 //--------------------------------------------------------------------
137 // Write Image
138 void rtk::HisImageIO::Write(const void* buffer)
139 {
140   std::ofstream file(m_FileName.c_str(), std::ios::out | std::ios::binary);
141
142   if ( file.fail() )
143     itkGenericExceptionMacro(<< "Could not open file (for writing): " << m_FileName);
144
145   m_HeaderSize = HEADER_INFO_SIZE + 32;
146   char szHeader[HEADER_INFO_SIZE + 32] = {
147     0x00, 0x70, 0x44, 0x00, 0x64, 0x00, 0x64, 0x00, 0x20, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0x00,
148     0x00, 0x04, 0x00, 0x04, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x18, 0x41,
149     0x04, 0x00, 0x40, 0x5F, 0x48, 0x01, 0x40, 0x00, 0x86, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
150     0x00, 0x00, 0x00, 0x00, 0x08, 0x63, 0x13, 0x00, 0xE8, 0x51, 0x13, 0x00, 0x5C, 0xE7, 0x12, 0x00,
151     0xFE, 0x2A, 0x49, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153     0x00, 0x00, 0x00, 0x00
154     };
155
156   /* Fill into the header the essentials
157      The 'iheader' in previous module is fixed to 0x20, and is included in szHeader.
158      The 'ulx' and 'uly' are fixed to 0x01, so that 'brx' and 'bry' reflect the dimensions of
159      the image.
160   */
161   const unsigned int ndim = GetNumberOfDimensions();
162   if ( (ndim < 2) || (ndim > 3) )
163     itkExceptionMacro( <<"Only 2D or 3D support");
164
165   szHeader[16] = (char)(GetDimensions(0) % 256);  // X-size    lsb
166   szHeader[17] = (char)(GetDimensions(0) / 256);  // X-size    msb
167   szHeader[18] = (char)(GetDimensions(1) % 256);  // Y-size    lsb
168   szHeader[19] = (char)(GetDimensions(1) / 256);  // Y-size    msb
169   if (ndim == 3) {
170     szHeader[20] = (char)(GetDimensions(0) % 256);  // NbFrames    lsb
171     szHeader[21] = (char)(GetDimensions(0) / 256);  // NbFrames    msb
172     }
173
174   switch (GetComponentType())
175     {
176     case itk::ImageIOBase::USHORT:
177       szHeader[32] = 4;
178       break;
179     //case AVS_TYPE_INTEGER:
180     //  szHeader[32] = 8;
181     //  break;
182     //case AVS_TYPE_REAL:
183     //  szHeader[32] = 16;
184     //  break;
185     default:
186       itkExceptionMacro(<< "Unsupported field type");
187       break;
188     }
189
190   file.write(szHeader, m_HeaderSize);
191   file.write( (const char *)buffer, GetImageSizeInBytes() );
192   file.close();
193 } ////