]> Creatis software - gdcm.git/blob - Testing/VTKTestWrite.cxx
* Test/VTKTestWriteSeq.cxx : add a VTK test to write sequences
[gdcm.git] / Testing / VTKTestWrite.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: VTKTestWrite.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/02/09 15:31:15 $
7   Version:   $Revision: 1.9 $
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 #include "vtkGdcmReader.h"
19 #include "vtkGdcmWriter.h"
20 #include "vtkImageViewer.h"
21 #include "vtkImageData.h"
22 #include "vtkRegressionTestImage.h"
23 #include "vtkImageClip.h"
24 #include "vtkImageTranslateExtent.h"
25 #include "vtkImageAppendComponents.h"
26 #include "vtkImageShiftScale.h"
27
28 #include <iostream>
29
30 //Generated file:
31 #include "gdcmDataImages.h"
32
33 #ifndef vtkFloatingPointType
34 #define vtkFloatingPointType float
35 #endif
36
37 int VTKWriteTest(vtkTesting *t,vtkImageViewer *viewer,
38                  std::string const &filename, 
39                  std::string const &referenceFileName)
40 {
41    int retVal = 0;  //by default this is an error
42
43    t->CleanArguments();
44    t->AddArgument("-D");
45    t->AddArgument( GDCM_DATA_ROOT );
46    t->AddArgument("-V");
47    t->AddArgument( referenceFileName.c_str() );
48    t->AddArgument("-T");
49    t->AddArgument( "." );
50
51    // Read the image   
52    vtkGdcmReader *origin = vtkGdcmReader::New();
53    origin->SetFileName( filename.c_str() );
54    origin->Update();
55
56    // Write the image
57    vtkGdcmWriter *writer = vtkGdcmWriter::New();
58    writer->SetFileName( "TestWrite.dcm" );
59    writer->SetInput(origin->GetOutput());
60    writer->Write();
61
62    origin->Delete();
63    writer->Delete();
64
65    // Read the written image   
66    vtkGdcmReader *reader = vtkGdcmReader::New();
67    reader->SetFileName( "TestWrite.dcm" );
68    reader->Update();
69
70    double range[2];
71    reader->GetOutput()->GetScalarRange(range);
72    int dim[3];
73    reader->GetOutput()->GetDimensions( dim );
74
75    // Show
76    if( viewer )
77    {
78       viewer->SetInput ( reader->GetOutput() );
79
80       viewer->SetColorWindow (range[1] - range[0]);
81       viewer->SetColorLevel (0.5 * (range[1] + range[0]));
82
83       viewer->SetSize(dim[0], dim[1]);
84       if(dim[2] != 1)
85       {
86          //For multifame dicom, take a snapshot of the center slice (+/- 1)
87          viewer->SetZSlice( dim[2] / 2 );
88       }
89       else
90       {
91          viewer->SetZSlice( 0 );
92       }
93
94       viewer->OffScreenRenderingOff();
95       viewer->Render();
96       viewer->SetInput(NULL);
97    }
98
99    //----------------------------------------------------------------------
100    // Transform the image to be RGB unsigned char, due to the requests in
101    // vtkTesting processing
102    // The pipeline is broken after each process to keep maximum of memory
103    vtkImageData *image=reader->GetOutput();
104    image->Update();
105    image->Register(NULL);
106    reader->Delete();
107
108    // Get the middle slice in the image
109    if(dim[2] != 1)
110    {
111       int *ext=image->GetExtent();
112       vtkImageClip *clip=vtkImageClip::New();
113       clip->SetInput(image);
114       clip->SetOutputWholeExtent(ext[0],ext[1],ext[2],ext[3],
115                                  ext[4]+dim[2] / 2,ext[4]+dim[2] / 2);
116       clip->ClipDataOn();
117       vtkImageTranslateExtent *translat=vtkImageTranslateExtent::New();
118       translat->SetInput(clip->GetOutput());
119       translat->SetTranslation(0,0,-ext[4]-dim[2] / 2);
120
121       image->UnRegister(NULL);
122       image=translat->GetOutput();
123       image->Update();
124       image->Register(NULL);
125       translat->SetOutput(NULL);
126       clip->Delete();
127       translat->Delete();
128    }
129
130    // Set an unsigned char image
131    // Shift/Scale the image 
132    image->Update();
133    vtkImageShiftScale *iss=vtkImageShiftScale::New();
134    iss->SetInput(image);
135    iss->SetOutputScalarTypeToUnsignedChar();
136    iss->SetShift(-range[0]);
137    iss->SetScale(255.0/(range[1]-range[0]));
138    iss->ClampOverflowOn();
139
140    image->UnRegister(NULL);
141    image=iss->GetOutput();
142    image->Update();
143    image->Register(NULL);
144    iss->Delete();
145
146    // Set 3 components to the image
147    if(image->GetNumberOfScalarComponents()==1)
148    {
149       vtkImageAppendComponents *x3=vtkImageAppendComponents::New();
150       x3->AddInput(image);
151       x3->AddInput(image);
152       x3->AddInput(image);
153
154       image->UnRegister(NULL);
155       image=x3->GetOutput();
156       image->Update();
157       image->Register(NULL);
158       x3->SetOutput(NULL);
159       x3->Delete();
160    }
161    // End of transform
162    //----------------------------------------------------------------------
163
164    // make test
165    ostrstream str;
166    retVal = t->RegressionTest(image,0.0,str);
167    image->UnRegister(NULL);
168
169    if( retVal != vtkTesting::PASSED )
170    {
171       std::cerr << str.str();
172    }
173    str.rdbuf()->freeze(1);
174
175    if( retVal == vtkTesting::PASSED )
176    {
177       std::cerr << "       ... OK" << std::endl;
178       return 0;
179    }
180    else
181    {
182       std::cerr << "       ... Failed" << std::endl;
183       return 1;
184    }
185 }
186
187 int VTKTestWrite(int argc, char *argv[])
188 {
189    bool show = false;
190    if( argc >= 2 )
191    {
192       if( std::string(argv[1]) == "-V" )
193       {
194          show = true;
195       }
196    }
197
198    int ret = 0;
199    vtkTesting *t = vtkTesting::New();
200    vtkImageViewer *viewer;
201    if( show )
202       viewer = vtkImageViewer::New();
203    else
204       viewer = NULL;
205
206    if( argc < 3+show )
207    {
208       std::cerr << "Usage: " << argv[0] << " [-V] image.dcm ref.png\n";
209       std::cerr << "   -V : to view images to the screen... \n"
210                 << "        this mode can generate errors in the test\n\n";
211    }
212    else
213    {
214       ret = VTKWriteTest(t,viewer,argv[1+show],argv[2+show]);
215       t->Delete();
216       if( viewer )
217          viewer->Delete();
218
219       return ret;
220    }
221
222    // Test for all images
223    int i = 0;
224    while( gdcmDataImages[i] != 0 )
225    {
226       std::string filename = GDCM_DATA_ROOT;
227       filename += "/";  //doh!
228       filename += gdcmDataImages[i];
229       std::cerr << "Filename: " << filename << std::endl;
230
231       //Extract name to find the png file matching:
232       std::string pngfile = gdcmDataImages[i++];
233       //pngfile.replace(pngfile.size()-3, 3, "png");
234       //More robust approach:
235       std::string::size_type dot_pos = pngfile.rfind( "." );
236       pngfile = pngfile.substr(0, dot_pos).append( ".png" );
237       pngfile.insert( 0, "Baseline/");
238       //std::cerr << "PNG file: " << pngfile << std::endl;
239
240       ret += VTKWriteTest(t,viewer,filename,pngfile);
241    }
242    t->Delete();
243    if( viewer )
244       viewer->Delete();
245
246    return ret;
247 }