]> Creatis software - gdcm.git/blob - vtk/vtkGdcmWriter.cxx
* Example/WriteDicomSimple.cxx : example to write a dicom file from nothing.
[gdcm.git] / vtk / vtkGdcmWriter.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: vtkGdcmWriter.cxx,v $
5   Language:  C++
6   Date:      $Date: 2004/12/09 11:31:52 $
7   Version:   $Revision: 1.5 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18                                                                                 
19 #include "gdcmHeader.h"
20 #include "gdcmFile.h"
21 #include "gdcmDebug.h"
22 #include "vtkGdcmWriter.h"
23
24 #include <vtkObjectFactory.h>
25 #include <vtkImageData.h>
26 #include <vtkPointData.h>
27 #include <vtkLookupTable.h>
28
29 vtkCxxRevisionMacro(vtkGdcmWriter, "$Revision: 1.5 $");
30 vtkStandardNewMacro(vtkGdcmWriter);
31
32 //-----------------------------------------------------------------------------
33 // Constructor / Destructor
34 vtkGdcmWriter::vtkGdcmWriter()
35 {
36    this->LookupTable = NULL;
37 }
38
39 vtkGdcmWriter::~vtkGdcmWriter()
40 {
41 }
42
43 //-----------------------------------------------------------------------------
44 // Print
45 void vtkGdcmWriter::PrintSelf(ostream& os, vtkIndent indent)
46 {
47    this->Superclass::PrintSelf(os,indent);
48 }
49
50 //-----------------------------------------------------------------------------
51 // Public
52
53 //-----------------------------------------------------------------------------
54 // Protected
55 /**
56  * Copy the image and reverse the Y axis
57  */
58 // The output datas must be deleted by the user of the method !!!
59 size_t ReverseData(vtkImageData *img,unsigned char **data)
60 {
61    int *dim = img->GetDimensions();
62    size_t lineSize = dim[0] * img->GetScalarSize()
63                    * img->GetNumberOfScalarComponents();
64    size_t planeSize = dim[1] * lineSize;
65    size_t size = dim[2] * planeSize;
66
67    *data = new unsigned char[size];
68
69    unsigned char *src = (unsigned char *)img->GetScalarPointer();
70    unsigned char *dst = *data + planeSize - lineSize;
71    for (int plane = 0; plane < dim[2]; plane++)
72    {
73       for (int line = 0; line < dim[1]; line++)
74       {
75          // Copy one line at proper destination:
76          memcpy((void*)dst, (void*)src, lineSize);
77
78          src += lineSize;
79          dst -= lineSize;
80       }
81       dst += 2 * planeSize;
82    }
83
84    return size;
85 }
86
87 /**
88  * Set the datas informations in the file
89  */
90 void SetImageInformation(gdcm::File *file,vtkImageData *image)
91 {
92    std::ostringstream str;
93
94    // Image size
95    int *dim = image->GetDimensions();
96
97    str.str("");
98    str << dim[0];
99    file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0011);
100
101    str.str("");
102    str << dim[1];
103    file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0010);
104
105    if(dim[2]>1)
106    {
107       str.str("");
108       str << dim[2];
109       file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0012);
110    }
111
112    // Pixel type
113    str.str("");
114    str << image->GetScalarSize()*8;
115    file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0100);
116    file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0101);
117
118    str.str("");
119    str << image->GetScalarSize()*8-1;
120    file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0102);
121
122    // Pixel Repr
123    // FIXME : what do we do when the ScalarType is 
124    // VTK_UNSIGNED_INT or VTK_UNSIGNED_LONG
125    str.str("");
126    if( image->GetScalarType() == VTK_UNSIGNED_CHAR ||
127        image->GetScalarType() == VTK_UNSIGNED_SHORT ||
128        image->GetScalarType() == VTK_UNSIGNED_INT ||
129        image->GetScalarType() == VTK_UNSIGNED_LONG )
130    {
131       str << "0"; // Unsigned
132    }
133    else
134    {
135       str << "1"; // Signed
136    }
137    file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0103);
138
139    // Samples per pixel
140    str.str("");
141    str << image->GetNumberOfScalarComponents();
142    file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0002);
143
144    // Spacing
145    double *sp = image->GetSpacing();
146
147    str.str("");
148    str << sp[0] << "\\" << sp[1];
149    file->ReplaceOrCreateByNumber(str.str(),0x0028,0x0030);
150    str.str("");
151    str << sp[2];
152    file->ReplaceOrCreateByNumber(str.str(),0x0018,0x0088);
153
154    // Origin
155    double *org = image->GetOrigin();
156
157    str.str("");
158    str << org[0] << "\\" << org[1] << "\\" << org[2];
159    file->ReplaceOrCreateByNumber(str.str(),0x0020,0x0032);
160
161    // Window / Level
162    double *rng=image->GetScalarRange();
163
164    str.str("");
165    str << rng[1]-rng[0];
166    file->ReplaceOrCreateByNumber(str.str(),0x0028,0x1051);
167    str.str("");
168    str << (rng[1]+rng[0])/2.0;
169    file->ReplaceOrCreateByNumber(str.str(),0x0028,0x1050);
170
171    // Pixels
172    unsigned char *data;
173    size_t size = ReverseData(image,&data);
174    file->SetImageData(data,size);
175 }
176
177 /**
178  * Write of the files
179  * The call to this method is recursive if there is some files to write
180  */ 
181 void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *image, ofstream *file)
182 {
183    (void)axis; // To avoid warning
184    if(file)
185    {
186       vtkErrorMacro( <<  "File musn't be opened");
187       return;
188    }
189
190    if( image->GetScalarType() == VTK_FLOAT || 
191        image->GetScalarType() == VTK_DOUBLE )
192    {
193       vtkErrorMacro(<< "Bad input type. Scalar type musn't be of type "
194                     << "VTK_FLOAT or VTKDOUBLE (found:"
195                     << image->GetScalarTypeAsString());
196       return;
197    }
198
199    WriteDcmFile(this->FileName,image);
200 }
201
202 void vtkGdcmWriter::RecursiveWrite(int axis, vtkImageData *image, 
203                                    vtkImageData *cache, ofstream *file)
204 {
205    (void)axis; // To avoid warning
206    (void)image; // To avoid warning
207    (void)cache; // To avoid warning
208    (void)file; // To avoid warning
209 }
210
211 void vtkGdcmWriter::WriteDcmFile(char *fileName,vtkImageData *image)
212 {
213    // From here, the write of the file begins
214    gdcm::File *dcmFile = new gdcm::File();
215
216    // Set the image informations
217    SetImageInformation(dcmFile,image);
218
219    // Write the image
220    if(!dcmFile->Write(fileName))
221    {
222       vtkErrorMacro( << "File "  <<  this->FileName  <<  "couldn't be written by "
223                      << " the gdcm library");
224       std::cerr << "not written \n";
225    }
226
227    delete dcmFile;
228 }
229
230 //-----------------------------------------------------------------------------
231 // Private
232
233 //-----------------------------------------------------------------------------