]> Creatis software - gdcm.git/blob - Testing/TestReadWriteReadCompare.cxx
Small exe, for unaware users
[gdcm.git] / Testing / TestReadWriteReadCompare.cxx
1 /*=========================================================================
2
3   Program:   gdcm
4   Module:    $RCSfile: TestReadWriteReadCompare.cxx,v $
5   Language:  C++
6   Date:      $Date: 2008/04/10 12:15:34 $
7   Version:   $Revision: 1.38 $
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 "gdcmFile.h"
19 #include "gdcmFileHelper.h"
20 #include "gdcmDebug.h"
21
22 #include "gdcmGlobal.h"
23 #include "gdcmTS.h"
24
25 #include <stdlib.h> // abs
26
27 //Generated file:
28 #include "gdcmDataImages.h"
29
30 const unsigned int MAX_NUMBER_OF_DIFFERENCE = 10;
31
32 int nb_of_success___;
33 int nb_of_failure___;
34 int nb_of_diffPM1___;
35 static int CompareInternal(std::string const &filename, std::string const &output)
36 {
37    std::cout << "----------------------------------------------------------------------" << std::endl
38              << "   Testing: " << filename << std::endl;
39
40    //////////////// Step 1 (see above description):
41
42    GDCM_NAME_SPACE::File *file = GDCM_NAME_SPACE::File::New( );
43    file->SetFileName( filename );
44    file->Load ();
45    if( !file->IsReadable() )
46    {
47       std::cout << "Failed" << std::endl
48                 << "Test::TestReadWriteReadCompare: Image not gdcm compatible:"
49                 << filename << std::endl;
50       file->Delete();
51       nb_of_failure___++;
52       return 1;
53    }
54    std::cout << "           step 1...";
55
56    //////////////// Step 2:
57    GDCM_NAME_SPACE::FileHelper *filehelper = GDCM_NAME_SPACE::FileHelper::New( file );
58    int dataSize       = filehelper->GetImageDataSize();
59    uint8_t *imageData = filehelper->GetImageData(); //EXTREMELY IMPORTANT
60           // Sure, it is : It's up to the user to decide if he wants to
61           // GetImageData or if he wants to GetImageDataRaw
62           // (even if we do it by setting a flag, *he* will have to decide)
63
64    //filehelper->SetImageData(imageData, dataSize);
65
66    filehelper->SetContentType(GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE); //  pixels remain unimpared
67    filehelper->SetWriteModeToRGB( );
68
69    filehelper->SetUserData(imageData,dataSize); // This one ensures the compression
70    filehelper->Write( output );
71
72    std::cout << "2...";
73
74    //////////////// Step 3:
75    GDCM_NAME_SPACE::File *fileout = GDCM_NAME_SPACE::File::New();
76    fileout->SetFileName( output );
77    fileout->Load();
78
79    if( !fileout->IsReadable() )
80    {
81       std::cout << "Failed" << std::endl
82                 << "Test::TestReadWriteReadCompare: Could not parse the newly "
83                 << "written image:" << filename << std::endl;
84       file->Delete();
85       filehelper->Delete();
86       fileout->Delete();
87       nb_of_failure___++;
88       return 1;
89    }
90
91    GDCM_NAME_SPACE::FileHelper *reread = GDCM_NAME_SPACE::FileHelper::New( fileout );
92
93    std::cout << "3...";
94    // For the next step:
95    int     dataSizeWritten   = reread->GetImageDataSize();
96    uint8_t *imageDataWritten = reread->GetImageData();
97  
98    //////////////// Step 4:
99    // Test the image size
100    if (file->GetXSize() != reread->GetFile()->GetXSize() ||
101        file->GetYSize() != reread->GetFile()->GetYSize() ||
102        file->GetZSize() != reread->GetFile()->GetZSize())
103    {
104       std::cout << "Failed" << std::endl
105          << "        Size differs: "
106          << "X: " << file->GetXSize() << " # "
107                   << reread->GetFile()->GetXSize() << " | "
108          << "Y: " << file->GetYSize() << " # "
109                   << reread->GetFile()->GetYSize() << " | "
110          << "Z: " << file->GetZSize() << " # "
111                   << reread->GetFile()->GetZSize() << std::endl;
112       file->Delete();
113       filehelper->Delete();
114       fileout->Delete();
115       reread->Delete();
116       nb_of_failure___++;      
117       return 1;
118    }
119
120    // Test the data size
121    // beware of odd length Pixel Element!
122    if (dataSize != dataSizeWritten)
123       std::cout << std::endl << "dataSize:" << dataSize << " dataSizeWritten:" << dataSizeWritten << std::endl;
124
125    int dataSizeFixed = dataSize - dataSize%2;
126    int dataSizeWrittenFixed = dataSizeWritten - dataSizeWritten%2;
127
128    if (dataSizeFixed != dataSizeWrittenFixed)
129    {
130       std::cout << "Failed" << std::endl
131          << "        Pixel areas lengths differ: "
132          << dataSize << " # " << dataSizeWritten << std::endl;
133       file->Delete();
134       filehelper->Delete();
135       fileout->Delete();
136       reread->Delete();
137       nb_of_failure___++;      
138       return 1;
139    }
140
141    // Test the data content
142
143    unsigned int nbDiff = 0;
144    if (memcmp(imageData, imageDataWritten, dataSizeFixed) !=0)
145    {
146       std::string PixelType = filehelper->GetFile()->GetPixelType();
147       std::string ts        = filehelper->GetFile()->GetTransferSyntax();
148
149        for(int i1=0; i1<dataSizeFixed; i1++)
150          if (abs ((int)imageData[i1]-(int)imageDataWritten[i1]) > 2) {
151             nbDiff++;
152            // break; // at debug time, keep line commented out; (uncommenting will save CPU time)
153          }
154
155        if (nbDiff!=0)
156        {
157           std::cout << std::endl << filename << " Failed : "
158                     << nbDiff/(file->GetBitsAllocated()/8) << " Pixels -amongst "
159                     << dataSizeFixed/(file->GetBitsAllocated()/8) << "- (" 
160                     << PixelType << " bAlloc:" << file->GetBitsAllocated() << " bStored:" << file->GetBitsStored()
161                     << ") differ (as expanded in memory)."
162                     << std::endl
163                     << "        compression : " 
164                     << GDCM_NAME_SPACE::Global::GetTS()->GetValue(ts) << std::endl;
165
166           std::cout << "   list of the first " << MAX_NUMBER_OF_DIFFERENCE
167                     << " bytes differing (pos : original - written) :"
168                     << std::endl;
169
170           for(unsigned int i=0, j1=0; i<dataSizeFixed && j1<MAX_NUMBER_OF_DIFFERENCE; i++)
171           {
172              if (abs ((int)imageData[i]-(int)imageDataWritten[i]) > 2)
173              {
174                 if (j1<MAX_NUMBER_OF_DIFFERENCE)
175                    std::cout << std::dec << "(" << i << " : "
176                      << std::hex
177                      << (int)(imageData[i]) << " - "
178                      << (int)(imageDataWritten[i]) << ") "
179                      << std::dec;
180                 ++j1;
181               }
182           }
183           std::cout << std::endl;
184
185           file->Delete();
186           filehelper->Delete();
187           fileout->Delete();
188           reread->Delete();
189           nb_of_failure___++;
190   
191           if (nbDiff/2 > 8 )  // last pixel of (DermaColorLossLess.dcm) is diferent. ?!?
192                               // I don't want it to break the testsuite
193              return 1;
194           else
195              return 0;
196        }      
197        else
198        {
199           std::cout << std::endl << filename << " : some pixels"
200                     << "  ("
201                     << PixelType << " bAlloc:" << file->GetBitsAllocated() << " bStored:" << file->GetBitsStored()
202                     << ") differ +/-1 (as expanded in memory)."
203                     << std::endl
204                     << "        compression : "
205                     << GDCM_NAME_SPACE::Global::GetTS()->GetValue(ts) << std::endl;
206
207           std::cout << "   list of the first " << MAX_NUMBER_OF_DIFFERENCE
208                     << " bytes differing (pos : original - written) :"
209                     << std::endl;
210
211           for(unsigned int i=0, j=0; i<dataSizeFixed && j<MAX_NUMBER_OF_DIFFERENCE; i++)
212           {
213              if (imageData[i] != imageDataWritten[i])
214              {
215                 std::cout << std::hex << "(" << i << " : " 
216                          << std::hex << (int)(imageData[i]) << " - "
217                          << std::hex << (int)(imageDataWritten[i]) << ") "
218                          << std::dec;
219                 ++j;
220               }
221           }
222           std::cout << std::endl;
223           nb_of_diffPM1___++;
224        }
225    }
226    else
227    {
228       nb_of_success___ ++;
229    }
230    std::cout << "=============== 4...OK." << std::endl ;
231    //////////////// Clean up:
232    file->Delete();
233    filehelper->Delete();
234    fileout->Delete();
235    reread->Delete();
236
237    return 0;
238 }
239
240 // -------------------------------------------------------------------------------------------
241
242 int TestReadWriteReadCompare(int argc, char *argv[]) 
243 {
244    int result = 0;
245    nb_of_success___ = 0;
246    nb_of_failure___ = 0;
247    nb_of_diffPM1___ = 0;
248    
249    if (argc == 4)
250       GDCM_NAME_SPACE::Debug::DebugOn();
251
252    if (argc >= 3)
253    {
254       const std::string input  = argv[1];
255       const std::string output = argv[2];
256       result += CompareInternal(input, output);
257    }
258    else if( argc > 4 || argc == 2 )
259    {
260       std::cout << "Please read the manual" << std::endl;
261    }
262    else
263    {
264       std::cout<< "Test::TestReadWriteReadCompare: description " << std::endl;
265       std::cout << "   For all images in gdcmData (and not blacklisted in "
266                    "Test/CMakeLists.txt)" << std::endl;
267       std::cout << "   apply the following multistep test: " << std::endl;
268       std::cout << "   step 1: parse the image (as gdcmFile) and call"
269                 << " IsReadable(). " << std::endl;
270       std::cout << "   step 2: write the corresponding image in DICOM V3 "
271                 << "with explicit Value Representation " << std::endl
272                 << "            in temporary file "
273                 << "TestReadWriteReadCompare.dcm." << std::endl;
274       std::cout << "   step 3: read the image written on step2 and call "
275                 << " IsReadable(). " << std::endl;
276       std::cout << "   step 4: compare (in memory with memcmp) that the two "
277                 << "images " << std::endl
278                 << "           match (as expanded by gdcm)." << std::endl;
279    
280       int i = 0;
281       int res =0;
282       while( gdcmDataImages[i] != 0 )
283       {
284          std::string filename = GDCM_DATA_ROOT;
285          filename += "/";
286          filename += gdcmDataImages[i];
287          res = CompareInternal(filename, "TestReadWriteReadCompare.dcm");
288
289          if (res == 1)
290          {
291             std::cout << "=============================== Failure on: " << gdcmDataImages[i] << std::endl;
292             result ++;
293          }
294          i ++;
295       }
296    }
297    std::cout << "==================================" << std::endl;
298    std::cout << "nb of success  " << nb_of_success___ << std::endl;
299    std::cout << "nb of failure  " << nb_of_failure___ << std::endl;
300    std::cout << "nb of diff+/-1 " << nb_of_diffPM1___ << std::endl;   
301    return result;
302 }