]> Creatis software - gdcm.git/blob - vtk/vtkGdcmReader.cxx
* vtk subdir added. Contains vtkGdcmReader.[cxx|h] a vtk class
[gdcm.git] / vtk / vtkGdcmReader.cxx
1 // $Header: /cvs/public/gdcm/vtk/vtkGdcmReader.cxx,v 1.1 2003/05/05 14:13:59 frog Exp $
2 #include "vtkGdcmReader.h"
3 #include "vtkByteSwap.h"
4 #include <stdio.h>
5 #include "vtkObjectFactory.h"
6 #include "vtkImageFlip.h"
7 #include "gdcm.h"
8
9 vtkGdcmReader::vtkGdcmReader()
10 {
11   // Constructor
12 }
13
14 //----------------------------------------------------------------------------
15 vtkGdcmReader::~vtkGdcmReader()
16
17   // FIXME free memory
18 }
19
20 // Configure the output e.g. WholeExtent, spacing, origin, scalar type...
21 void vtkGdcmReader::ExecuteInformation()
22 {
23   //FIXME free any old memory
24       
25   // if the user has not set the extent, but has set the VOI
26   // set the zaxis extent to the VOI z axis
27   if (this->DataExtent[4]==0 && this->DataExtent[5] == 0 &&
28      (this->DataVOI[4] || this->DataVOI[5]))
29     {
30     this->DataExtent[4] = this->DataVOI[4];
31     this->DataExtent[5] = this->DataVOI[5];
32     }
33
34   this->ComputeInternalFileName(this->DataExtent[4]);
35   
36   // Check for file existence.
37   FILE *fp;
38   fp = fopen(this->InternalFileName,"rb");
39   if (!fp)
40     {
41     vtkErrorMacro("Unable to open file " << this->InternalFileName);
42     return;
43     }
44   fclose(fp);
45
46   // Check for Gdcm parsability
47   gdcmHeader GdcmHeader(this->InternalFileName);
48   if (!GdcmHeader.IsReadable())
49     {
50     vtkErrorMacro("Gdcm cannot parse file " << this->InternalFileName);
51     return;
52     }
53
54   int NX = GdcmHeader.GetXSize();
55   int NY = GdcmHeader.GetYSize();
56   int NZ = GdcmHeader.GetZSize();
57   vtkDebugMacro("Image dimension as read from Gdcm:" <<
58                 NX << " " << NY << " " << NZ);
59
60   if(NZ>1) this->SetFileDimensionality(3);
61
62   // When the user has set the VOI, check it's coherence with the file content.
63   if (this->DataVOI[0] || this->DataVOI[1] || 
64       this->DataVOI[2] || this->DataVOI[3] ||
65       this->DataVOI[4] || this->DataVOI[5])
66     { 
67     if ((this->DataVOI[0] < 0) ||
68         (this->DataVOI[1] >= NX) ||
69         (this->DataVOI[2] < 0) ||
70         (this->DataVOI[3] >= NY) ||
71         (this->DataVOI[4] < 0) ||
72         (this->DataVOI[5] >= NZ))
73       {
74       vtkWarningMacro("The requested VOI is larger than the file's ("
75                       << this->InternalFileName << ") extent ");
76       this->DataVOI[0] = 0;
77       this->DataVOI[1] = NX - 1;
78       this->DataVOI[2] = 0;
79       this->DataVOI[3] = NY - 1;
80       this->DataVOI[4] = 0;
81       this->DataVOI[5] = NZ - 1;
82       }
83     }
84
85   // Positionate the Extent.
86   this->DataExtent[0] = 0;
87   this->DataExtent[1] = NX - 1;
88   this->DataExtent[2] = 0;
89   this->DataExtent[3] = NY - 1;
90   if(this->GetFileDimensionality()==3)
91     {
92       this->DataExtent[4] = 0;
93       this->DataExtent[5] = NZ - 1;
94     }
95   
96   // We don't need to positionate the Endian related stuff (by using
97   // this->SetDataByteOrderToBigEndian() or SetDataByteOrderToLittleEndian()
98   // since the // reading of the file is done by gdcm
99
100   // But we need to set up the data type for downstream filters:
101   string type = GdcmHeader.GetPixelType();
102   if      ( type == "8U" )
103     {
104     vtkDebugMacro("8 bits unsigned image");
105     this->SetDataScalarTypeToUnsignedChar(); 
106     }
107   else if ( type == "8S" )
108     {
109     vtkErrorMacro("Cannot handle 8 bit signed files");
110     return;
111     }
112   else if ( type == "16U" )
113     {
114     vtkDebugMacro("16 bits unsigned image");
115     this->SetDataScalarTypeToUnsignedShort();
116     }
117   else if ( type == "16S" )
118     {
119     vtkDebugMacro("16 bits signed image");
120     this->SetDataScalarTypeToShort();
121     //vtkErrorMacro("Cannot handle 16 bit signed files");
122     }
123   else if ( type == "32U" )
124     {
125     vtkDebugMacro("32 bits unsigned image");
126     vtkDebugMacro("WARNING: forced to signed int !");
127     this->SetDataScalarTypeToInt();
128     }
129   else if ( type == "32S" )
130     {
131     vtkDebugMacro("32 bits signed image");
132     this->SetDataScalarTypeToInt();
133     }
134   else
135     {
136     vtkErrorMacro("Bad File Type " << this->InternalFileName
137                                    << "Type " << type);
138     return;
139     }
140
141   vtkImageReader::ExecuteInformation();
142 }
143
144 // Update -> UpdateData -> Execute -> ExecuteData (see vtkSource.cxx for
145 // last step.
146 // This function (redefinition of vtkImageReader::ExecuteData, see 
147 // VTK/IO/vtkImageReader.cxx) reads a data from a file. The datas
148 // extent/axes are assumed to be the
149 // same as the file extent/order.
150 void vtkGdcmReader::ExecuteData(vtkDataObject *output)
151 {
152   if (!this->FileName)
153     {
154     vtkErrorMacro("A valid FileName must be specified.");
155     return;
156     }
157
158   vtkImageData *data = this->AllocateOutputData(output);
159   data->SetExtent(this->DataExtent);
160   data->GetPointData()->GetScalars()->SetName("ImageFile");
161
162   int size =
163     (this->DataExtent[1] - this->DataExtent[0]+1) *
164     (this->DataExtent[3] - this->DataExtent[2]+1) *
165     (this->DataExtent[5] - this->DataExtent[4]+1) *
166     2;
167   gdcmFile GdcmFile(this->InternalFileName);
168   size = GdcmFile.GetImageDataSize();
169   unsigned char *mem = new unsigned char [size];
170   if ( size != GdcmFile.GetImageDataSize() )
171     {
172     vtkDebugMacro("Inconsistency with GetImageDataSize");
173     vtkDebugMacro("Number of scalar components"
174                   << this->NumberOfScalarComponents);
175     }
176   GdcmFile.GetImageDataIntoVector((void*)mem, size);
177   data->GetPointData()->GetScalars()->SetVoidArray(mem, size, 0);
178   //vtkImageFlip * Flip = vtkImageFlip::New();
179   //Flip->SetInput(data);
180   //Flip->Update();
181   //data = Flip->GetOutput();
182   //Flip->SetInput(NULL);
183   this->Modified();
184
185 }
186
187 void vtkGdcmReader::PrintSelf(ostream& os, vtkIndent indent)
188 {
189   vtkImageReader::PrintSelf(os,indent);
190   //CLEANME os << indent << "TypeSize: " << this->TypeSize << "\n";
191 }