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 *=========================================================================*/
22 #include "rtkHndImageIO.h"
23 #include <itkMetaDataObject.h>
25 //--------------------------------------------------------------------
26 // Read Image Information
27 void rtk::HndImageIO::ReadImageInformation()
32 fp = fopen (m_FileName.c_str(), "rb");
34 itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);
37 nelements += fread ( (void *) hnd.sFileType, sizeof(char), 32, fp);
38 nelements += fread ( (void *) &hnd.FileLength, sizeof(itk::uint32_t), 1, fp);
39 nelements += fread ( (void *) hnd.sChecksumSpec, sizeof(char), 4, fp);
40 nelements += fread ( (void *) &hnd.nCheckSum, sizeof(itk::uint32_t), 1, fp);
41 nelements += fread ( (void *) hnd.sCreationDate, sizeof(char), 8, fp);
42 nelements += fread ( (void *) hnd.sCreationTime, sizeof(char), 8, fp);
43 nelements += fread ( (void *) hnd.sPatientID, sizeof(char), 16, fp);
44 nelements += fread ( (void *) &hnd.nPatientSer, sizeof(itk::uint32_t), 1, fp);
45 nelements += fread ( (void *) hnd.sSeriesID, sizeof(char), 16, fp);
46 nelements += fread ( (void *) &hnd.nSeriesSer, sizeof(itk::uint32_t), 1, fp);
47 nelements += fread ( (void *) hnd.sSliceID, sizeof(char), 16, fp);
48 nelements += fread ( (void *) &hnd.nSliceSer, sizeof(itk::uint32_t), 1, fp);
49 nelements += fread ( (void *) &hnd.SizeX, sizeof(itk::uint32_t), 1, fp);
50 nelements += fread ( (void *) &hnd.SizeY, sizeof(itk::uint32_t), 1, fp);
51 nelements += fread ( (void *) &hnd.dSliceZPos, sizeof(double), 1, fp);
52 nelements += fread ( (void *) hnd.sModality, sizeof(char), 16, fp);
53 nelements += fread ( (void *) &hnd.nWindow, sizeof(itk::uint32_t), 1, fp);
54 nelements += fread ( (void *) &hnd.nLevel, sizeof(itk::uint32_t), 1, fp);
55 nelements += fread ( (void *) &hnd.nPixelOffset, sizeof(itk::uint32_t), 1, fp);
56 nelements += fread ( (void *) hnd.sImageType, sizeof(char), 4, fp);
57 nelements += fread ( (void *) &hnd.dGantryRtn, sizeof(double), 1, fp);
58 nelements += fread ( (void *) &hnd.dSAD, sizeof(double), 1, fp);
59 nelements += fread ( (void *) &hnd.dSFD, sizeof(double), 1, fp);
60 nelements += fread ( (void *) &hnd.dCollX1, sizeof(double), 1, fp);
61 nelements += fread ( (void *) &hnd.dCollX2, sizeof(double), 1, fp);
62 nelements += fread ( (void *) &hnd.dCollY1, sizeof(double), 1, fp);
63 nelements += fread ( (void *) &hnd.dCollY2, sizeof(double), 1, fp);
64 nelements += fread ( (void *) &hnd.dCollRtn, sizeof(double), 1, fp);
65 nelements += fread ( (void *) &hnd.dFieldX, sizeof(double), 1, fp);
66 nelements += fread ( (void *) &hnd.dFieldY, sizeof(double), 1, fp);
67 nelements += fread ( (void *) &hnd.dBladeX1, sizeof(double), 1, fp);
68 nelements += fread ( (void *) &hnd.dBladeX2, sizeof(double), 1, fp);
69 nelements += fread ( (void *) &hnd.dBladeY1, sizeof(double), 1, fp);
70 nelements += fread ( (void *) &hnd.dBladeY2, sizeof(double), 1, fp);
71 nelements += fread ( (void *) &hnd.dIDUPosLng, sizeof(double), 1, fp);
72 nelements += fread ( (void *) &hnd.dIDUPosLat, sizeof(double), 1, fp);
73 nelements += fread ( (void *) &hnd.dIDUPosVrt, sizeof(double), 1, fp);
74 nelements += fread ( (void *) &hnd.dIDUPosRtn, sizeof(double), 1, fp);
75 nelements += fread ( (void *) &hnd.dPatientSupportAngle, sizeof(double), 1, fp);
76 nelements += fread ( (void *) &hnd.dTableTopEccentricAngle, sizeof(double), 1, fp);
77 nelements += fread ( (void *) &hnd.dCouchVrt, sizeof(double), 1, fp);
78 nelements += fread ( (void *) &hnd.dCouchLng, sizeof(double), 1, fp);
79 nelements += fread ( (void *) &hnd.dCouchLat, sizeof(double), 1, fp);
80 nelements += fread ( (void *) &hnd.dIDUResolutionX, sizeof(double), 1, fp);
81 nelements += fread ( (void *) &hnd.dIDUResolutionY, sizeof(double), 1, fp);
82 nelements += fread ( (void *) &hnd.dImageResolutionX, sizeof(double), 1, fp);
83 nelements += fread ( (void *) &hnd.dImageResolutionY, sizeof(double), 1, fp);
84 nelements += fread ( (void *) &hnd.dEnergy, sizeof(double), 1, fp);
85 nelements += fread ( (void *) &hnd.dDoseRate, sizeof(double), 1, fp);
86 nelements += fread ( (void *) &hnd.dXRayKV, sizeof(double), 1, fp);
87 nelements += fread ( (void *) &hnd.dXRayMA, sizeof(double), 1, fp);
88 nelements += fread ( (void *) &hnd.dMetersetExposure, sizeof(double), 1, fp);
89 nelements += fread ( (void *) &hnd.dAcqAdjustment, sizeof(double), 1, fp);
90 nelements += fread ( (void *) &hnd.dCTProjectionAngle, sizeof(double), 1, fp);
91 nelements += fread ( (void *) &hnd.dCTNormChamber, sizeof(double), 1, fp);
92 nelements += fread ( (void *) &hnd.dGatingTimeTag, sizeof(double), 1, fp);
93 nelements += fread ( (void *) &hnd.dGating4DInfoX, sizeof(double), 1, fp);
94 nelements += fread ( (void *) &hnd.dGating4DInfoY, sizeof(double), 1, fp);
95 nelements += fread ( (void *) &hnd.dGating4DInfoZ, sizeof(double), 1, fp);
96 nelements += fread ( (void *) &hnd.dGating4DInfoTime, sizeof(double), 1, fp);
98 if(nelements != /*char*/120 + /*itk::uint32_t*/10 + /*double*/41)
99 itkGenericExceptionMacro(<< "Could not read header data in " << m_FileName);
102 itkGenericExceptionMacro(<< "Could not close file: " << m_FileName);
104 /* Convert hnd to ITK image information */
105 SetNumberOfDimensions(2);
106 SetDimensions(0, hnd.SizeX);
107 SetDimensions(1, hnd.SizeY);
108 SetSpacing(0, hnd.dIDUResolutionX);
109 SetSpacing(1, hnd.dIDUResolutionY);
110 SetOrigin(0, -0.5*(hnd.SizeX-1)*hnd.dIDUResolutionX); //SR: assumed centered
111 SetOrigin(1, -0.5*(hnd.SizeY-1)*hnd.dIDUResolutionY); //SR: assumed centered
112 SetComponentType(itk::ImageIOBase::UINT);
114 /* Store important meta information in the meta data dictionary */
115 itk::EncapsulateMetaData<double>(this->GetMetaDataDictionary(), "dCTProjectionAngle", hnd.dCTProjectionAngle);
118 //--------------------------------------------------------------------
119 bool rtk::HndImageIO::CanReadFile(const char* FileNameToRead)
121 std::string filename(FileNameToRead);
122 const std::string::size_type it = filename.find_last_of( "." );
123 std::string fileExt( filename, it+1, filename.length() );
125 if (fileExt != std::string("hnd") )
130 //--------------------------------------------------------------------
131 // Read Image Content
132 void rtk::HndImageIO::Read(void * buffer)
136 itk::uint32_t *buf = (itk::uint32_t*)buffer;
137 unsigned char *pt_lut;
140 int lut_idx, lut_off;
147 fp = fopen (m_FileName.c_str(), "rb");
149 itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);
151 pt_lut = (unsigned char*) malloc (sizeof (unsigned char) * GetDimensions(0) * GetDimensions(1) );
154 if(fseek (fp, 1024, SEEK_SET) != 0)
155 itkGenericExceptionMacro(<< "Could not seek to image data in: " << m_FileName);
157 size_t nbytes = (GetDimensions(1)-1)*GetDimensions(0) / 4;
158 if(nbytes != fread (pt_lut, sizeof(unsigned char), nbytes, fp))
159 itkGenericExceptionMacro(<< "Could not read image LUT in: " << m_FileName);
162 for (i = 0; i < GetDimensions(0); i++) {
163 if(1 != fread (&a, sizeof(itk::uint32_t), 1, fp))
164 itkGenericExceptionMacro(<< "Could not read first row in: " << m_FileName);
168 /* Read first pixel of second row */
169 if(1 != fread (&a, sizeof(itk::uint32_t), 1, fp))
170 itkGenericExceptionMacro(<< "Could not read first pixel of second row");
173 /* Decompress the rest */
176 while (i < GetDimensions(0) * GetDimensions(1) ) {
177 itk::uint32_t r11, r12, r21;
179 r11 = buf[i-GetDimensions(0)-1];
180 r12 = buf[i-GetDimensions(0)];
204 num_read = fread (&dc, sizeof(unsigned char), 1, fp);
205 if (num_read != 1) goto read_error;
209 num_read = fread (&ds, sizeof(unsigned short), 1, fp);
210 if (num_read != 1) goto read_error;
214 num_read = fread (&dl, sizeof(itk::uint32_t), 1, fp);
215 if (num_read != 1) goto read_error;
220 buf[i] = r21 + r12 + diff - r11;
227 itkGenericExceptionMacro(<< "Could not close file: " << m_FileName);
232 itkGenericExceptionMacro(<< "Error reading hnd file");
235 itkGenericExceptionMacro(<< "Could not close file: " << m_FileName);
239 //--------------------------------------------------------------------
240 bool rtk::HndImageIO::CanWriteFile(const char* itkNotUsed(FileNameToWrite))
245 //--------------------------------------------------------------------
247 void rtk::HndImageIO::Write(const void* itkNotUsed(buffer))