]> Creatis software - gdcm.git/blob - src/gdcmHeaderHelper.cxx
* Fix a few delete/delete[] mismatch
[gdcm.git] / src / gdcmHeaderHelper.cxx
1 // $Header: /cvs/public/gdcm/src/Attic/gdcmHeaderHelper.cxx,v 1.2 2003/09/09 08:46:32 malaterre Exp $
2
3 //This is needed when compiling in debug mode
4 #ifdef _MSC_VER
5 #pragma warning ( disable : 4800 )
6 // 'identifier' : class 'type' needs to have dll-interface to be used by
7 // clients of class 'type2'
8 #pragma warning ( disable : 4251 )
9 // 'identifier' : identifier was truncated to 'number' characters in the
10 // debug information
11 #pragma warning ( disable : 4786 )
12 #endif //_MSC_VER
13
14 #include "gdcmHeaderHelper.h"
15 #include "gdcmUtil.h" //for debug
16 #include <math.h>
17 #include <algorithm>
18 #include <string.h> //for bzero
19 using namespace std;
20
21 //directory manipulation (os indep).
22 //cygwin ???? -> _WIN32 ??
23 #ifdef _MSC_VER 
24 #include <windows.h> 
25 int GetDir(string dPath, list<string> &filenames)
26 {
27   WIN32_FIND_DATA FileData; 
28   HANDLE hFile; 
29   hFile = FindFirstFile(dPath.c_str(), &FileData); 
30   if ( hFile == INVALID_HANDLE_VALUE ) 
31   { 
32     //No files !
33     return false; 
34   } 
35   
36   filenames.push_back( FileData.cFileName );
37   while( FindNextFile(hFile, &FileData ) != 0)
38   { 
39     filenames.push_back( FileData.cFileName );
40   }
41   return true;
42 }
43
44 #else
45 #include <dirent.h>
46
47 int GetDir(string dPath, list<string> &filenames)
48 {
49  DIR *dir = opendir( dPath.c_str() );
50  struct dirent *entry;
51  while((entry = readdir(dir)) != NULL)
52  {
53 //   if( strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
54    if( strncmp(entry->d_name, ".", 1) != 0 )
55    {
56       filenames.push_back( dPath + "/" + entry->d_name );
57    }
58  }
59  closedir(dir);
60  return true;
61 }
62
63 #endif
64
65 //----------------------------------------------------------------------------
66 /**
67  * \ingroup gdcmHeaderHelper
68  * \brief   cstor
69  */
70 gdcmHeaderHelper::gdcmHeaderHelper() : gdcmHeader( )
71 {
72 }
73 //----------------------------------------------------------------------------
74 /**
75  * \ingroup gdcmHeaderHelper
76  * \brief   cstor
77  */
78 gdcmHeaderHelper::gdcmHeaderHelper(const char *InFilename, 
79     bool exception_on_error) : gdcmHeader( InFilename , exception_on_error)
80 {
81 }
82 //----------------------------------------------------------------------------
83 /**
84  * \ingroup gdcmHeaderHelper
85  * \brief   Return the size (in bytes) of a single pixel of data.
86  * @return  The size in bytes of a single pixel of data.
87  *
88  */
89 int gdcmHeaderHelper::GetPixelSize() {
90    string PixelType = GetPixelType();
91    if (PixelType == "8U"  || PixelType == "8S")
92       return 1;
93    if (PixelType == "16U" || PixelType == "16S")
94       return 2;
95    if (PixelType == "32U" || PixelType == "32S")
96       return 4;
97    dbg.Verbose(0, "gdcmHeader::GetPixelSize: Unknown pixel type");
98    return 0;
99 }
100 //----------------------------------------------------------------------------
101 /**
102  * \ingroup gdcmHeaderHelper
103  * \brief   Build the Pixel Type of the image.
104  *          Possible values are:
105  *          - 8U  unsigned  8 bit,
106  *          - 8S    signed  8 bit,
107  *          - 16U unsigned 16 bit,
108  *          - 16S   signed 16 bit,
109  *          - 32U unsigned 32 bit,
110  *          - 32S   signed 32 bit,
111  * \warning 12 bit images appear as 16 bit.
112  * @return  
113  */
114 string gdcmHeaderHelper::GetPixelType() {
115    string BitsAlloc;
116    BitsAlloc = GetElValByName("Bits Allocated");
117    if (BitsAlloc == "gdcm::Unfound") {
118       dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
119       BitsAlloc = string("16");
120    }
121    if (BitsAlloc == "12")
122       BitsAlloc = string("16");
123
124    string Signed;
125    Signed = GetElValByName("Pixel Representation");
126    if (Signed == "gdcm::Unfound") {
127       dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation");
128       BitsAlloc = string("0");
129    }
130    if (Signed == "0")
131       Signed = string("U");
132    else
133       Signed = string("S");
134
135    return( BitsAlloc + Signed);
136 }
137 //----------------------------------------------------------------------------
138 /**
139   * \ingroup gdcmHeaderHelper
140   * \brief gets the info from 0028,0030 : Pixel Spacing
141   * \           else 1.
142   * @return X dimension of a pixel
143   */
144 float gdcmHeaderHelper::GetXSpacing() {
145     float xspacing, yspacing;
146     string StrSpacing = GetPubElValByNumber(0x0028,0x0030);
147
148     if (StrSpacing == "gdcm::Unfound") {
149        dbg.Verbose(0, "gdcmHeader::GetXSpacing: unfound Pixel Spacing (0028,0030)");
150        return 1.;
151      }
152    if( sscanf( StrSpacing.c_str(), "%f\\%f", &xspacing, &yspacing) != 2)
153      return 0.;
154    //else
155    return xspacing;
156 }
157 //----------------------------------------------------------------------------
158 /**
159   * \ingroup gdcmHeaderHelper
160   * \brief gets the info from 0028,0030 : Pixel Spacing
161   * \           else 1.
162   * @return Y dimension of a pixel
163   */
164 float gdcmHeaderHelper::GetYSpacing() {
165    float xspacing, yspacing;
166    string StrSpacing = GetPubElValByNumber(0x0028,0x0030);
167   
168    if (StrSpacing == "gdcm::Unfound") {
169       dbg.Verbose(0, "gdcmHeader::GetYSpacing: unfound Pixel Spacing (0028,0030)");
170       return 1.;
171     }
172   if( sscanf( StrSpacing.c_str(), "%f\\%f", &xspacing, &yspacing) != 2)
173     return 0.;
174   if (yspacing == 0.) {
175     dbg.Verbose(0, "gdcmHeader::GetYSpacing: gdcmData/CT-MONO2-8-abdo.dcm problem");
176     // seems to be a bug in the header ...
177     sscanf( StrSpacing.c_str(), "%f\\0\\%f", &xspacing, &yspacing);
178   }
179   return yspacing;
180
181
182 //----------------------------------------------------------------------------
183 /**
184   *\ingroup gdcmHeaderHelper
185   *\brief gets the info from 0018,0088 : Space Between Slices
186   *\               else from 0018,0050 : Slice Thickness
187   *\               else 1.
188   * @return Z dimension of a voxel-to be
189   */
190 float gdcmHeaderHelper::GetZSpacing() {
191    // TODO : translate into English
192    // Spacing Between Slices : distance entre le milieu de chaque coupe
193    // Les coupes peuvent etre :
194    //   jointives     (Spacing between Slices = Slice Thickness)
195    //   chevauchantes (Spacing between Slices < Slice Thickness)
196    //   disjointes    (Spacing between Slices > Slice Thickness)
197    // Slice Thickness : epaisseur de tissus sur laquelle est acquis le signal
198    //   ca interesse le physicien de l'IRM, pas le visualisateur de volumes ...
199    //   Si le Spacing Between Slices est absent, 
200    //   on suppose que les coupes sont jointives
201    
202    string StrSpacingBSlices = GetPubElValByNumber(0x0018,0x0088);
203
204    if (StrSpacingBSlices == "gdcm::Unfound") {
205       dbg.Verbose(0, "gdcmHeader::GetZSpacing: unfound StrSpacingBSlices");
206       string StrSliceThickness = GetPubElValByNumber(0x0018,0x0050);       
207       if (StrSliceThickness == "gdcm::Unfound")
208          return 1.;
209       else
210          // if no 'Spacing Between Slices' is found, 
211          // we assume slices join together
212          // (no overlapping, no interslice gap)
213          // if they don't, we're fucked up
214          return atof(StrSliceThickness.c_str());  
215    } else {
216       return atof(StrSpacingBSlices.c_str());
217    }
218 }
219
220 //----------------------------------------------------------------------------
221 //
222 // Image Position Patient                              (0020,0032):
223 // If not found (ACR_NEMA) we try Image Position       (0020,0030)
224 // If not found (ACR-NEMA), we consider Slice Location (0020,1041)
225 //                                   or Location       (0020,0050) 
226 // as the Z coordinate, 
227 // 0. for all the coordinates if nothing is found
228
229 // TODO : find a way to inform the caller nothing was found
230 // TODO : How to tell the caller a wrong number of values was found?
231
232 /**
233   * \ingroup gdcmHeaderHelper
234   * \brief gets the info from 0020,0032 : Image Position Patient
235   *\                else from 0020,0030 : Image Position (RET)
236   *\                else 0.
237   * @return up-left image corner position
238   */
239 float gdcmHeaderHelper::GetXOrigin() {
240     float xImPos, yImPos, zImPos;  
241     string StrImPos = GetPubElValByNumber(0x0020,0x0032);
242
243     if (StrImPos == "gdcm::Unfound") {
244        dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position Patient (0020,0032)");
245        StrImPos = GetPubElValByNumber(0x0020,0x0030); // For ACR-NEMA images
246        if (StrImPos == "gdcm::Unfound") {
247           dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position (RET) (0020,0030)");
248           // How to tell the caller nothing was found ?
249          return 0.;
250        }  
251      }
252    if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
253      return 0.;
254    return xImPos;
255 }
256 //----------------------------------------------------------------------------
257 /**
258   * \ingroup gdcmHeaderHelper
259   * \brief gets the info from 0020,0032 : Image Position Patient
260   * \               else from 0020,0030 : Image Position (RET)
261   * \               else 0.
262   * @return up-left image corner position
263   */
264 float gdcmHeaderHelper::GetYOrigin() {
265     float xImPos, yImPos, zImPos;
266     string StrImPos = GetPubElValByNumber(0x0020,0x0032);
267
268     if (StrImPos == "gdcm::Unfound") {
269        dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position Patient (0020,0032)");
270        StrImPos = GetPubElValByNumber(0x0020,0x0030); // For ACR-NEMA images
271        if (StrImPos == "gdcm::Unfound") {
272           dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position (RET) (0020,0030)");
273           // How to tell the caller nothing was found ?
274            return 0.;
275        }  
276      }
277    if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
278      return 0.;
279    return yImPos;
280 }
281 //----------------------------------------------------------------------------
282 /**
283   * \ingroup gdcmHeaderHelper
284   * \brief gets the info from 0020,0032 : Image Position Patient
285   * \               else from 0020,0030 : Image Position (RET)
286   * \               else from 0020,1041 : Slice Location
287   * \               else from 0020,0050 : Location
288   * \               else 0.
289   * @return up-left image corner position
290   */
291 float gdcmHeaderHelper::GetZOrigin() {
292    float xImPos, yImPos, zImPos; 
293    string StrImPos = GetPubElValByNumber(0x0020,0x0032);
294    if (StrImPos != "gdcm::Unfound") {
295       if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) {
296          dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position Patient (0020,0032)");
297          return 0.;  // bug in the element 0x0020,0x0032
298       } else {
299          return zImPos;
300       }    
301    }  
302    StrImPos = GetPubElValByNumber(0x0020,0x0030); // For ACR-NEMA images
303    if (StrImPos != "gdcm::Unfound") {
304       if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) {
305          dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position (RET) (0020,0030)");
306          return 0.;  // bug in the element 0x0020,0x0032
307       } else {
308          return zImPos;
309       }    
310    }                
311    string StrSliceLocation = GetPubElValByNumber(0x0020,0x1041);// for *very* old ACR-NEMA images
312    if (StrSliceLocation != "gdcm::Unfound") {
313       if( sscanf( StrSliceLocation.c_str(), "%f", &zImPos) !=1) {
314          dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Slice Location (0020,1041)");
315          return 0.;  // bug in the element 0x0020,0x1041
316       } else {
317          return zImPos;
318       }
319    }   
320    dbg.Verbose(0, "gdcmHeader::GetZImagePosition: unfound Slice Location (0020,1041)");
321    string StrLocation = GetPubElValByNumber(0x0020,0x0050);
322    if (StrLocation != "gdcm::Unfound") {
323       if( sscanf( StrLocation.c_str(), "%f", &zImPos) !=1) {
324          dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Location (0020,0050)");
325          return 0.;  // bug in the element 0x0020,0x0050
326       } else {
327          return zImPos;
328       }
329    }
330    dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Location (0020,0050)");  
331    return 0.; // Hopeless
332 }
333 //----------------------------------------------------------------------------
334 /**
335   * \ingroup gdcmHeaderHelper
336   * \brief gets the info from 0020,0013 : Image Number
337   * \               else 0.
338   * @return image number
339   */
340 int gdcmHeaderHelper::GetImageNumber() {
341   //The function i atoi() takes the address of an area of memory as parameter and converts 
342   //the string stored at that location to an integer using the external decimal to internal
343   //binary conversion rules. This may be preferable to sscanf() since atoi() is a much smaller,
344   // simpler and faster function. sscanf() can do all possible conversions whereas atoi() can 
345   //only do single decimal integer conversions.
346   string StrImNumber = GetPubElValByNumber(0x0020,0x0013); //0020 0013 IS REL Image Number
347   if (StrImNumber != "gdcm::Unfound") {
348     return atoi( StrImNumber.c_str() );
349   }
350   return 0;   //Hopeless
351 }
352 //----------------------------------------------------------------------------
353 /**
354   * \ingroup gdcmHeaderHelper
355   * \brief gets the info from 0008,0060 : Modality
356   * @return ModalityType
357   */
358 ModalityType gdcmHeaderHelper::GetModality(void) {
359   string StrModality = GetPubElValByNumber(0x0008,0x0060); //0008 0060 CS ID Modality
360   if (StrModality != "gdcm::Unfound") {
361     if ( StrModality.find("CR") < StrModality.length())
362     {
363       return CR;
364     }
365     else if ( StrModality.find("CT") < StrModality.length() )
366     {
367       return CT;
368     }
369     else if ( StrModality.find("MR") < StrModality.length())
370     {
371       return MR;
372     }
373     else if ( StrModality.find("NM") < StrModality.length())
374     {
375       return NM;
376     }
377     else if ( StrModality.find("OT") < StrModality.length())
378     {
379       return OT;
380     }
381     else if ( StrModality.find("US") < StrModality.length())
382     {
383       return US;
384     }
385     else if ( StrModality.find("XA") < StrModality.length())
386     {
387       return XA;
388     }
389     else
390     {
391       //throw error return value ???
392       // specified <> unknow in our database
393       return Unknow;
394     }
395   }
396   return Unknow;
397 }
398
399 //----------------------------------------------------------------------------
400 string gdcmHeaderHelper::GetStudyUID()
401 {
402   return GetPubElValByNumber(0x0020,0x000d); //!0020 000d UI REL Study Instance UID
403 }
404 //----------------------------------------------------------------------------
405 string gdcmHeaderHelper::GetSeriesUID()
406 {
407   return GetPubElValByNumber(0x0020,0x000e); //!0020 000e UI REL Series Instance UID
408 }
409 //----------------------------------------------------------------------------
410 string gdcmHeaderHelper::GetClassUID()
411 {
412   return GetPubElValByNumber(0x0008,0x0016); //!0008 0016 UI ID SOP Class UID
413 }
414 //----------------------------------------------------------------------------
415 string gdcmHeaderHelper::GetInstanceUID()
416 {
417   return GetPubElValByNumber(0x0008,0x0018); //!0008 0018 UI ID SOP Instance UID
418 }
419
420
421
422
423
424
425
426
427
428 gdcmSerieHeaderHelper::~gdcmSerieHeaderHelper()
429 {
430   //! \todo
431   for (list<gdcmHeaderHelper*>::iterator it  = CoherentGdcmFileList.begin();
432         it != CoherentGdcmFileList.end(); it++)
433   {
434     delete *it;
435   }
436   CoherentGdcmFileList.clear();
437 }
438 //----------------------------------------------------------------------------
439 /**
440   * \ingroup gdcmHeaderHelper
441   * \brief gets the info from 0020,0037 : Image Orientation Patient
442   * @return cosines of image orientation patient
443   */
444 void gdcmHeaderHelper::GetImageOrientationPatient( float* iop ) {
445
446   //iop is supposed to be float[6]
447   iop[0] = iop[1] = iop[2] = iop[3] = iop[4] = iop[5] = 0;
448   
449   string StrImOriPat = GetPubElValByNumber(0x0020,0x0037); // 0020 0037 DS REL Image Orientation (Patient)
450   if (StrImOriPat != "gdcm::Unfound") {
451     if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f", 
452             &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) {
453          dbg.Verbose(0, "gdcmHeader::GetImageOrientationPatient: wrong Image Orientation Patient (0020,0037)");
454          return ;  // bug in the element 0x0020,0x0037
455     } 
456     else
457       return ;
458   }
459   
460   //For ACR-NEMA
461   StrImOriPat = GetPubElValByNumber(0x0020,0x0035); //0020 0035 DS REL Image Orientation (RET)
462   if (StrImOriPat != "gdcm::Unfound") {
463     if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f", 
464             &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) {
465          dbg.Verbose(0, "gdcmHeader::GetImageOrientationPatient: wrong Image Orientation Patient (0020,0035)");
466          return ;  // bug in the element 0x0020,0x0035
467     } 
468     else
469       return ;
470   }
471 }
472
473 //----------------------------------------------------------------------------
474 /**
475   * \ingroup gdcmHeaderHelper
476   * \brief add a gdcmFile to the list based on file name
477   */
478 void gdcmSerieHeaderHelper::AddFileName(string filename)
479 {
480   gdcmHeaderHelper *GdcmFile = new gdcmHeaderHelper( filename.c_str() );
481   this->CoherentGdcmFileList.push_back( GdcmFile );
482 }
483 //----------------------------------------------------------------------------
484 /**
485   * \ingroup gdcmHeaderHelper
486   * \brief add a gdcmFile to the list
487   */
488 void gdcmSerieHeaderHelper::AddGdcmFile(gdcmHeaderHelper *file)
489 {
490   this->CoherentGdcmFileList.push_back( file );
491 }
492 //----------------------------------------------------------------------------
493 /**
494   * \ingroup gdcmHeaderHelper
495   * \brief \todo
496   */
497 void gdcmSerieHeaderHelper::SetDirectory(string dir)
498 {
499   list<string> filenames_list;
500   GetDir(dir, filenames_list);  //OS specific
501   
502   for(list<string>::iterator it = filenames_list.begin(); it !=
503   filenames_list.end(); it++)
504   {
505     gdcmHeaderHelper *file = new gdcmHeaderHelper( it->c_str() );
506     this->CoherentGdcmFileList.push_back( file );
507   }
508 }
509 //----------------------------------------------------------------------------
510 //This could be implemented in a 'Strategy Pattern' approach
511 //But as I don't know how to do it, I leave it this way
512 //BTW, this is also a Strategy, I don't know this is the best approcah :)
513 void gdcmSerieHeaderHelper::OrderGdcmFileList()
514 {
515   if( ImagePositionPatientOrdering() )
516   {
517     return ;
518   }
519   else if( ImageNumberOrdering() )
520   {
521     return ;
522   }
523   else
524   {
525     FileNameOrdering();
526   }
527 }
528 //----------------------------------------------------------------------------
529 /**
530   * \ingroup gdcmHeaderHelper
531   * \brief 
532     We may order, considering :
533       -# Image Number
534       -# Image Position Patient
535       -# More to come :)
536 */
537 //based on Jolinda's algorithm
538 bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering()
539 {
540   //iop is calculated based on the file file
541   float *cosines = new float[6];
542   float normal[3];
543   float ipp[3];
544   float dist;
545   float min, max;
546   bool first = true;
547   int n=0;
548   vector<float> distlist;
549
550   //!\todo rewrite this for loop.
551   for (list<gdcmHeaderHelper*>::iterator it  = CoherentGdcmFileList.begin();
552         it != CoherentGdcmFileList.end(); it++)
553   {
554     if(first) {
555       (*it)->GetImageOrientationPatient(cosines);
556       
557       //You only have to do this once for all slices in the volume. Next, for
558       //each slice, calculate the distance along the slice normal using the IPP
559       //tag ("dist" is initialized to zero before reading the first slice) :
560       normal[0] = cosines[1]*cosines[5] - cosines[2]*cosines[4];
561       normal[1] = cosines[2]*cosines[3] - cosines[0]*cosines[5];
562       normal[2] = cosines[0]*cosines[4] - cosines[1]*cosines[3];
563   
564       ipp[0] = (*it)->GetXOrigin();
565       ipp[1] = (*it)->GetYOrigin();
566       ipp[2] = (*it)->GetZOrigin();
567
568       dist = 0;
569       for (int i = 0; i < 3; ++i)
570           dist += normal[i]*ipp[i];
571     
572       if( dist == 0 )
573       {
574         delete[] cosines;
575         return false;
576       }
577
578       distlist.push_back( dist );
579
580       max = min = dist;
581       first = false;
582     }
583     else {
584       ipp[0] = (*it)->GetXOrigin();
585       ipp[1] = (*it)->GetYOrigin();
586       ipp[2] = (*it)->GetZOrigin();
587   
588       dist = 0;
589       for (int i = 0; i < 3; ++i)
590           dist += normal[i]*ipp[i];
591
592       if( dist == 0 )
593       {
594         delete[] cosines;
595         return false;
596       }
597
598       
599       distlist.push_back( dist );
600
601       min = (min < dist) ? min : dist;
602       max = (max > dist) ? max : dist;
603     }
604     n++;
605   }
606
607     //Then I order the slices according to the value "dist". Finally, once
608     //I've read in all the slices, I calculate the z-spacing as the difference
609     //between the "dist" values for the first two slices.
610     vector<gdcmHeaderHelper*> CoherentGdcmFileVector(n);
611     //CoherentGdcmFileVector.reserve( n );
612     CoherentGdcmFileVector.resize( n );
613     //assert( CoherentGdcmFileVector.capacity() >= n );
614
615     float step = (max - min)/(n - 1);
616     int pos;
617     n = 0;
618     
619     //VC++ don't understand what scope is !! it -> it2
620     for (list<gdcmHeaderHelper*>::iterator it2  = CoherentGdcmFileList.begin();
621         it2 != CoherentGdcmFileList.end(); it2++, n++)
622     {
623       //2*n sort algo !!
624       //Assumption: all files are present (no one missing)
625       pos = (int)( fabs( (distlist[n]-min)/step) + .5 );
626             
627       CoherentGdcmFileVector[pos] = *it2;
628     }
629
630   CoherentGdcmFileList.clear();  //this doesn't delete list's element, node only
631   
632   //VC++ don't understand what scope is !! it -> it3
633   for (vector<gdcmHeaderHelper*>::iterator it3  = CoherentGdcmFileVector.begin();
634         it3 != CoherentGdcmFileVector.end(); it3++)
635   {
636     CoherentGdcmFileList.push_back( *it3 );
637   }
638
639   distlist.clear();
640   CoherentGdcmFileVector.clear();
641   delete[] cosines;
642   
643   return true;
644 }
645 //----------------------------------------------------------------------------
646 //Based on Image Number
647 bool gdcmSerieHeaderHelper::ImageNumberOrdering()
648 {
649   int min, max, pos;
650   int n = 0;//CoherentGdcmFileList.size(); //O(N) operation !!
651   unsigned char *partition;
652   
653   list<gdcmHeaderHelper*>::iterator it  = CoherentGdcmFileList.begin();
654   min = max = (*it)->GetImageNumber();
655
656   for (; it != CoherentGdcmFileList.end(); it++, n++)
657   {
658     pos = (*it)->GetImageNumber();
659
660     //else
661     min = (min < pos) ? min : pos;
662   }
663
664   //bzeros(partition, n); //Cette fonction est déconseillée, utilisez plutôt memset.
665   partition = new unsigned char[n];
666   memset(partition, 0, n);
667
668   vector<gdcmHeaderHelper*> CoherentGdcmFileVector(n);
669
670   //VC++ don't understand what scope is !! it -> it2
671   for (list<gdcmHeaderHelper*>::iterator it2  = CoherentGdcmFileList.begin();
672         it2 != CoherentGdcmFileList.end(); it2++)
673   {
674     pos = (*it2)->GetImageNumber();
675     CoherentGdcmFileVector[pos - min] = *it2;
676     partition[pos - min]++;
677   }
678   
679   unsigned char mult;
680   for(int i=0; i<n ; i++)
681   {
682     mult *= partition[i];
683   }
684
685   //VC++ don't understand what scope is !! it -> it3
686   CoherentGdcmFileList.clear();  //this doesn't delete list's element, node only
687   for (vector<gdcmHeaderHelper*>::iterator it3  = CoherentGdcmFileVector.begin();
688         it3 != CoherentGdcmFileVector.end(); it3++)
689   {
690     CoherentGdcmFileList.push_back( *it3 );
691   }
692   CoherentGdcmFileVector.clear();
693   
694   delete[] partition;
695   return mult;
696 }
697 //----------------------------------------------------------------------------
698 bool gdcmSerieHeaderHelper::FileNameOrdering()
699 {
700   //using the sort
701   //sort(CoherentGdcmFileList.begin(), CoherentGdcmFileList.end());
702   return true;
703 }
704 //----------------------------------------------------------------------------
705 list<gdcmHeaderHelper*> &gdcmSerieHeaderHelper::GetGdcmFileList()
706 {
707   return CoherentGdcmFileList;
708 }
709 //----------------------------------------------------------------------------