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