]> Creatis software - clitk.git/blob - common/clitkHndImageIO.cxx
bd8e51855c848605ec4a45111503077645852ef4
[clitk.git] / common / clitkHndImageIO.cxx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18
19 // std include
20 #include <stdio.h>
21
22 // clitk include
23 #include "clitkHndImageIO.h"
24 #include "clitkCommon.h"
25
26 // itk include
27 #include <itkMetaDataObject.h>
28
29 //--------------------------------------------------------------------
30 // Read Image Information
31 void clitk::HndImageIO::ReadImageInformation()
32 {
33   Hnd_header hnd;
34   FILE *fp;
35
36   fp = fopen (m_FileName.c_str(), "rb");
37   if (fp == NULL)
38     itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);
39
40   fread ((void *) hnd.sFileType, sizeof(char), 32, fp);
41   fread ((void *) &hnd.FileLength, sizeof(uint32_t), 1, fp);
42   fread ((void *) hnd.sChecksumSpec, sizeof(char), 4, fp);
43   fread ((void *) &hnd.nCheckSum, sizeof(uint32_t), 1, fp);
44   fread ((void *) hnd.sCreationDate, sizeof(char), 8, fp);
45   fread ((void *) hnd.sCreationTime, sizeof(char), 8, fp);
46   fread ((void *) hnd.sPatientID, sizeof(char), 16, fp);
47   fread ((void *) &hnd.nPatientSer, sizeof(uint32_t), 1, fp);
48   fread ((void *) hnd.sSeriesID, sizeof(char), 16, fp);
49   fread ((void *) &hnd.nSeriesSer, sizeof(uint32_t), 1, fp);
50   fread ((void *) hnd.sSliceID, sizeof(char), 16, fp);
51   fread ((void *) &hnd.nSliceSer, sizeof(uint32_t), 1, fp);
52   fread ((void *) &hnd.SizeX, sizeof(uint32_t), 1, fp);
53   fread ((void *) &hnd.SizeY, sizeof(uint32_t), 1, fp);
54   fread ((void *) &hnd.dSliceZPos, sizeof(double), 1, fp);
55   fread ((void *) hnd.sModality, sizeof(char), 16, fp);
56   fread ((void *) &hnd.nWindow, sizeof(uint32_t), 1, fp);
57   fread ((void *) &hnd.nLevel, sizeof(uint32_t), 1, fp);
58   fread ((void *) &hnd.nPixelOffset, sizeof(uint32_t), 1, fp);
59   fread ((void *) hnd.sImageType, sizeof(char), 4, fp);
60   fread ((void *) &hnd.dGantryRtn, sizeof(double), 1, fp);
61   fread ((void *) &hnd.dSAD, sizeof(double), 1, fp);
62   fread ((void *) &hnd.dSFD, sizeof(double), 1, fp);
63   fread ((void *) &hnd.dCollX1, sizeof(double), 1, fp);
64   fread ((void *) &hnd.dCollX2, sizeof(double), 1, fp);
65   fread ((void *) &hnd.dCollY1, sizeof(double), 1, fp);
66   fread ((void *) &hnd.dCollY2, sizeof(double), 1, fp);
67   fread ((void *) &hnd.dCollRtn, sizeof(double), 1, fp);
68   fread ((void *) &hnd.dFieldX, sizeof(double), 1, fp);
69   fread ((void *) &hnd.dFieldY, sizeof(double), 1, fp);
70   fread ((void *) &hnd.dBladeX1, sizeof(double), 1, fp);
71   fread ((void *) &hnd.dBladeX2, sizeof(double), 1, fp);
72   fread ((void *) &hnd.dBladeY1, sizeof(double), 1, fp);
73   fread ((void *) &hnd.dBladeY2, sizeof(double), 1, fp);
74   fread ((void *) &hnd.dIDUPosLng, sizeof(double), 1, fp);
75   fread ((void *) &hnd.dIDUPosLat, sizeof(double), 1, fp);
76   fread ((void *) &hnd.dIDUPosVrt, sizeof(double), 1, fp);
77   fread ((void *) &hnd.dIDUPosRtn, sizeof(double), 1, fp);
78   fread ((void *) &hnd.dPatientSupportAngle, sizeof(double), 1, fp);
79   fread ((void *) &hnd.dTableTopEccentricAngle, sizeof(double), 1, fp);
80   fread ((void *) &hnd.dCouchVrt, sizeof(double), 1, fp);
81   fread ((void *) &hnd.dCouchLng, sizeof(double), 1, fp);
82   fread ((void *) &hnd.dCouchLat, sizeof(double), 1, fp);
83   fread ((void *) &hnd.dIDUResolutionX, sizeof(double), 1, fp);
84   fread ((void *) &hnd.dIDUResolutionY, sizeof(double), 1, fp);
85   fread ((void *) &hnd.dImageResolutionX, sizeof(double), 1, fp);
86   fread ((void *) &hnd.dImageResolutionY, sizeof(double), 1, fp);
87   fread ((void *) &hnd.dEnergy, sizeof(double), 1, fp);
88   fread ((void *) &hnd.dDoseRate, sizeof(double), 1, fp);
89   fread ((void *) &hnd.dXRayKV, sizeof(double), 1, fp);
90   fread ((void *) &hnd.dXRayMA, sizeof(double), 1, fp);
91   fread ((void *) &hnd.dMetersetExposure, sizeof(double), 1, fp);
92   fread ((void *) &hnd.dAcqAdjustment, sizeof(double), 1, fp);
93   fread ((void *) &hnd.dCTProjectionAngle, sizeof(double), 1, fp);
94   fread ((void *) &hnd.dCTNormChamber, sizeof(double), 1, fp);
95   fread ((void *) &hnd.dGatingTimeTag, sizeof(double), 1, fp);
96   fread ((void *) &hnd.dGating4DInfoX, sizeof(double), 1, fp);
97   fread ((void *) &hnd.dGating4DInfoY, sizeof(double), 1, fp);
98   fread ((void *) &hnd.dGating4DInfoZ, sizeof(double), 1, fp);
99   fread ((void *) &hnd.dGating4DInfoTime, sizeof(double), 1, fp);
100   fclose (fp);
101
102   /* Convert hnd to ITK image information */
103   SetNumberOfDimensions(2);
104   SetDimensions(0, hnd.SizeX);
105   SetDimensions(1, hnd.SizeY);
106   SetSpacing(0, hnd.dIDUResolutionX);
107   SetSpacing(1, hnd.dIDUResolutionY);
108   SetOrigin(0, -0.5*(hnd.SizeX-1)*hnd.dIDUResolutionX); //SR: assumed centered
109   SetOrigin(1, -0.5*(hnd.SizeY-1)*hnd.dIDUResolutionY); //SR: assumed centered
110   SetComponentType(itk::ImageIOBase::UINT);
111
112   /* Store important meta information in the meta data dictionary */
113   itk::EncapsulateMetaData<double>(this->GetMetaDataDictionary(), "dCTProjectionAngle", hnd.dCTProjectionAngle);
114   //itk::ExposeMetaData<double>( this->GetMetaDataDictionary(), &(hnd.dCTProjectionAngle), "dCTProjectionAngle");
115 }
116
117 //--------------------------------------------------------------------
118 bool clitk::HndImageIO::CanReadFile(const char* FileNameToRead)
119 {
120   std::string filename(FileNameToRead);
121   std::string filenameext = GetExtension(filename);
122   if (filenameext != std::string("hnd")) return false;
123   return true;
124 }
125
126 //--------------------------------------------------------------------
127 // Read Image Content
128 void clitk::HndImageIO::Read(void * buffer)
129 {
130   FILE *fp;
131
132   uint32_t* buf = (uint32_t*)buffer;
133   unsigned char *pt_lut;
134   uint32_t a;
135   float b;
136   unsigned char v;
137   int lut_idx, lut_off;
138   size_t num_read;
139   char dc;
140   short ds;
141   long dl, diff=0;
142   uint32_t i;
143
144   fp = fopen (m_FileName.c_str(), "rb");
145   if (fp == NULL)
146     itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);
147
148   pt_lut = (unsigned char*) malloc (sizeof (unsigned char) * GetDimensions(0) * GetDimensions(1));
149
150   /* Read LUT */
151   fseek (fp, 1024, SEEK_SET);
152   fread (pt_lut, sizeof(unsigned char), (GetDimensions(1)-1)*GetDimensions(0) / 4, fp);
153
154   /* Read first row */
155   for (i = 0; i < GetDimensions(0); i++) {
156     fread (&a, sizeof(uint32_t), 1, fp);
157     buf[i] = a;
158     b = a;
159   }
160
161   /* Read first pixel of second row */
162   fread (&a, sizeof(uint32_t), 1, fp);
163   buf[i++] = a;
164   b = a;
165
166   /* Decompress the rest */
167   lut_idx = 0;
168   lut_off = 0;
169   while (i < GetDimensions(0) * GetDimensions(1)) {
170     uint32_t r11, r12, r21;
171
172     r11 = buf[i-GetDimensions(0)-1];
173     r12 = buf[i-GetDimensions(0)];
174     r21 = buf[i-1];
175     v = pt_lut[lut_idx];
176     switch (lut_off) {
177     case 0:
178       v = v & 0x03;
179       lut_off ++;
180       break;
181     case 1:
182       v = (v & 0x0C) >> 2;
183       lut_off ++;
184       break;
185     case 2:
186       v = (v & 0x30) >> 4;
187       lut_off ++;
188       break;
189     case 3:
190       v = (v & 0xC0) >> 6;
191       lut_off = 0;
192       lut_idx ++;
193       break;
194     }
195     switch (v) {
196     case 0:
197       num_read = fread (&dc, sizeof(unsigned char), 1, fp);
198       if (num_read != 1) goto read_error;
199       diff = dc;
200       break;
201     case 1:
202       num_read = fread (&ds, sizeof(unsigned short), 1, fp);
203       if (num_read != 1) goto read_error;
204       diff = ds;
205       break;
206     case 2:
207       num_read = fread (&dl, sizeof(uint32_t), 1, fp);
208       if (num_read != 1) goto read_error;
209       diff = dl;
210       break;
211     }
212
213     buf[i] = r21 + r12 + diff - r11;
214     b = buf[i];
215     i++;
216   }
217
218   /* Clean up */
219   free (pt_lut);
220   fclose (fp);
221   return;
222
223 read_error:
224
225   itkGenericExceptionMacro(<< "Error reading hnd file");
226   free (pt_lut);
227   fclose (fp);
228   return;
229 }
230
231 //--------------------------------------------------------------------
232 bool clitk::HndImageIO::CanWriteFile(const char* FileNameToWrite)
233 {
234   return false;
235 }
236
237 //--------------------------------------------------------------------
238 // Write Image
239 void clitk::HndImageIO::Write(const void* buffer)
240 {
241 }