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