1 /*=========================================================================
4 Module: $RCSfile: gdcmDicomDir.cxx,v $
6 Date: $Date: 2004/08/02 16:42:14 $
7 Version: $Revision: 1.63 $
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.htm for details.
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.
17 =========================================================================*/
21 #include <sys/types.h>
29 #include "gdcmDicomDir.h"
30 #include "gdcmDicomDirStudy.h"
31 #include "gdcmDicomDirSerie.h"
32 #include "gdcmDicomDirImage.h"
33 #include "gdcmDirList.h"
35 #include "gdcmDebug.h"
36 #include "gdcmGlobal.h"
37 #include "gdcmHeader.h"
38 #include "gdcmSeqEntry.h"
39 #include "gdcmSQItem.h"
40 #include "gdcmValEntry.h"
42 //-----------------------------------------------------------------------------
43 // For full DICOMDIR description, see:
44 // PS 3.3-2003, pages 731-750
45 //-----------------------------------------------------------------------------
46 // Constructor / Destructor
49 * \ingroup gdcmDicomDir
50 * \brief Constructor : creates an empty gdcmDicomDir
52 gdcmDicomDir::gdcmDicomDir()
57 std::string pathBidon = "Bidon"; // Sorry, NULL not allowed ...
58 SetElement(pathBidon, GDCM_DICOMDIR_META, NULL); // Set the META elements
63 * \brief Constructor Parses recursively the directory and creates the DicomDir
64 * or uses an already built DICOMDIR, depending on 'parseDir' value.
65 * @param FileName name
66 * - of the root directory (parseDir = true)
67 * - of the DICOMDIR (parseDir = false)
68 * @param parseDir boolean
69 * - true if user passed an entry point
70 * and wants to explore recursively the directories
71 * - false if user passed an already built DICOMDIR file
74 gdcmDicomDir::gdcmDicomDir(std::string const & fileName, bool parseDir ):
75 gdcmDocument( fileName )
77 // que l'on ai passe un root directory ou un DICOMDIR
78 // et quelle que soit la valeur de parseDir,
79 // on a deja lance gdcmDocument
82 // gdcmDocument already executed
83 // if user passed a root directory, sure we didn't get anything
85 if ( TagHT.begin() == TagHT.end() )
87 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : entry HT empty");
89 if ( fileName.size() == 1 && fileName[0] == '.' )
91 // user passed '.' as Name
92 // we get current directory name
93 char* dummy = new char[1000];
94 getcwd(dummy, (size_t)1000);
95 std::cout << "Directory to parse : [" << dummy << "]" << std::endl;
96 SetFileName( dummy ); // will be converted into a string
97 delete[] dummy; // no longer needed
102 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory"
103 " and create the DicomDir");
108 /// \todo if parseDir == false, it should be tagged as an error
109 // NON ! il suffit d'appeler ParseDirectory()
110 // apres le constructeur
115 // Directory record sequence
116 gdcmDocEntry *e = GetDocEntryByNumber(0x0004, 0x1220);
119 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : NO Directory record"
120 " sequence (0x0004,0x1220)");
121 /// \todo FIXME : what do we do when the parsed file IS NOT a
129 * \brief Canonical destructor
131 gdcmDicomDir::~gdcmDicomDir()
133 SetStartMethod(NULL);
134 SetProgressMethod(NULL);
142 for(ListDicomDirPatient::iterator cc = patients.begin();
150 //-----------------------------------------------------------------------------
153 * \brief Canonical Printer
155 void gdcmDicomDir::Print(std::ostream &os)
159 metaElems->SetPrintLevel(PrintLevel);
160 metaElems->Print(os);
162 for(ListDicomDirPatient::iterator cc = patients.begin();
163 cc != patients.end();
166 (*cc)->SetPrintLevel( PrintLevel );
171 //-----------------------------------------------------------------------------
174 * \brief This predicate, based on hopefully reasonable heuristics,
175 * decides whether or not the current header was properly parsed
176 * and contains the mandatory information for being considered as
177 * a well formed and usable DicomDir.
178 * @return true when gdcmDocument is the one of a reasonable DicomDir,
181 bool gdcmDicomDir::IsReadable()
183 if( !gdcmDocument::IsReadable() )
191 if( patients.size() <= 0 )
200 * \brief Sets all fields to NULL
203 void gdcmDicomDir::Initialize()
206 progressMethod = NULL;
208 startMethodArgDelete = NULL;
209 progressMethodArgDelete = NULL;
210 endMethodArgDelete = NULL;
223 * \ingroup gdcmDicomDir
224 * \brief fills the whole structure, starting from a root Directory
226 void gdcmDicomDir::ParseDirectory()
228 CreateDicomDirChainedList( GetFileName() );
233 * \ingroup gdcmDicomDir
234 * \brief Set the start method to call when the parsing of the directory starts
235 * @param method Method to call
236 * @param arg Argument to pass to the method
237 * @param argDelete Argument
238 * \warning In python : the arg parameter isn't considered
240 void gdcmDicomDir::SetStartMethod(gdcmMethod *method, void *arg,
241 gdcmMethod *argDelete )
243 if( startArg && startMethodArgDelete )
245 startMethodArgDelete( startArg );
248 startMethod = method;
250 startMethodArgDelete = argDelete;
254 * \ingroup gdcmDicomDir
255 * \brief Set the method to delete the argument
256 * The argument is destroyed when the method is changed or when the
258 * @param method Method to call to delete the argument
260 void gdcmDicomDir::SetStartMethodArgDelete(gdcmMethod *method)
262 startMethodArgDelete = method;
266 * \ingroup gdcmDicomDir
267 * \brief Set the progress method to call when the parsing of the directory progress
268 * @param method Method to call
269 * @param arg Argument to pass to the method
270 * @param argDelete Argument
271 * \warning In python : the arg parameter isn't considered
273 void gdcmDicomDir::SetProgressMethod(gdcmMethod *method, void *arg,
274 gdcmMethod *argDelete )
276 if( progressArg && progressMethodArgDelete )
278 progressMethodArgDelete( progressArg );
281 progressMethod = method;
283 progressMethodArgDelete = argDelete;
287 * \ingroup gdcmDicomDir
288 * \brief Set the method to delete the argument
289 * The argument is destroyed when the method is changed or when the
291 * @param method Method to call to delete the argument
293 void gdcmDicomDir::SetProgressMethodArgDelete(gdcmMethod *method)
295 progressMethodArgDelete = method;
299 * \ingroup gdcmDicomDir
300 * \brief Set the end method to call when the parsing of the directory ends
301 * @param method Method to call
302 * @param arg Argument to pass to the method
303 * @param argDelete Argument
304 * \warning In python : the arg parameter isn't considered
306 void gdcmDicomDir::SetEndMethod(gdcmMethod *method, void *arg,
307 gdcmMethod *argDelete )
309 if( endArg && endMethodArgDelete )
311 endMethodArgDelete( endArg );
316 endMethodArgDelete = argDelete;
320 * \ingroup gdcmDicomDir
321 * \brief Set the method to delete the argument
322 * The argument is destroyed when the method is changed or when the class
324 * @param method Method to call to delete the argument
326 void gdcmDicomDir::SetEndMethodArgDelete(gdcmMethod *method)
328 endMethodArgDelete = method;
332 * \ingroup gdcmDicomDir
333 * \brief writes on disc a DICOMDIR
334 * \ warning does NOT add the missing elements in the header :
335 * it's up to the user doing it !
336 * \todo : to be re-written using the DICOMDIR tree-like structure
337 * *not* the chained list
338 * (does NOT exist if the DICOMDIR is user-forged !)
339 * @param fileName file to be written to
340 * @return false only when fail to open
343 bool gdcmDicomDir::Write(std::string const & fileName)
345 FILE * fp1 = fopen(fileName.c_str(), "wb");
348 printf("Failed to open(write) File [%s] \n", fileName.c_str());
352 char * filePreamble = new char[128];
353 fwrite(filePreamble,128,1,fp1);
354 fwrite("DICM",4,1,fp1);
355 delete[] filePreamble;
356 UpdateDirectoryRecordSequenceLength();
364 * \brief Writes in a file using the tree-like structure.
365 * @param _fp already open file pointer
368 void gdcmDicomDir::WriteEntries(FILE *) //_fp
370 /// \todo (?) tester les echecs en ecriture
371 /// (apres chaque fwrite, dans le WriteEntry)
374 /* TODO : to go on compiling
376 gdcmDicomDirMeta *ptrMeta;
377 ListDicomDirPatient::iterator itPatient;
378 ListDicomDirStudy::iterator itStudy;
379 ListDicomDirSerie::iterator itSerie;
380 ListDicomDirImage::iterator itImage;
383 ptrMeta= GetDicomDirMeta();
384 for(i=ptrMeta->debut();i!=ptrMeta->fin();++i) {
385 WriteEntry(*i,_fp, gdcmExplicitVR);
388 itPatient = GetDicomDirPatients().begin();
389 while ( itPatient != GetDicomDirPatients().end() ) {
390 for(i=(*itPatient)->debut();i!=(*itPatient)->fin();++i) {
391 WriteEntry(*i,_fp, gdcmExplicitVR);
393 itStudy = ((*itPatient)->GetDicomDirStudies()).begin();
394 while (itStudy != (*itPatient)->GetDicomDirStudies().end() ) {
395 for(i=(*itStudy)->debut();i!=(*itStudy)->fin();++i) {
396 WriteEntry(*i,_fp, gdcmExplicitVR);
398 itSerie = ((*itStudy)->GetDicomDirSeries()).begin();
399 while (itSerie != (*itStudy)->GetDicomDirSeries().end() ) {
400 for(i=(*itSerie)->debut();i!=(*itSerie)->fin();++i) {
401 WriteEntry(*i,_fp, gdcmExplicitVR);
403 itImage = ((*itSerie)->GetDicomDirImages()).begin();
404 while (itImage != (*itSerie)->GetDicomDirImages().end() ) {
405 for(i=(*itImage)->debut();i!=(*itImage)->fin();++i) {
406 WriteEntry(*i,_fp, gdcmExplicitVR);
419 //-----------------------------------------------------------------------------
423 * \ingroup gdcmDicomDir
424 * \brief create a gdcmDocument-like chained list from a root Directory
425 * @param path entry point of the tree-like structure
427 void gdcmDicomDir::CreateDicomDirChainedList(std::string const & path)
430 gdcmDirList fileList(path,1); // gets recursively the file list
431 unsigned int count = 0;
438 for( gdcmDirList::iterator it = fileList.begin();
439 it != fileList.end();
442 progress = (float)(count+1)/(float)fileList.size();
443 CallProgressMethod();
449 header = new gdcmHeader( it->c_str() );
453 "gdcmDicomDir::CreateDicomDirChainedList: "
454 "failure in new Header ",
457 if( header->IsReadable() )
459 // Add the file header to the chained list:
460 list.push_back(header);
462 "gdcmDicomDir::CreateDicomDirChainedList: readable ",
472 // sorts Patient/Study/Serie/
473 std::sort(list.begin(), list.end(), gdcmDicomDir::HeaderLessThan );
475 std::string tmp = fileList.GetDirName();
477 //for each Header of the chained list, add/update the Patient/Study/Serie/Image info
478 SetElements(tmp, list);
484 * \ingroup gdcmDicomDir
485 * \brief adds *the* Meta to a partially created DICOMDIR
488 /// \todo FIXME : Heuuuuu ! Il prend les Entries du Document deja parse,
489 /// il ne fabrique rien !
491 gdcmDicomDirMeta * gdcmDicomDir::NewMeta()
493 gdcmDicomDirMeta *m = new gdcmDicomDirMeta( &TagHT );
494 for ( TagDocEntryHT::iterator cc = TagHT.begin();
495 cc != TagHT.end(); ++cc)
497 m->AddDocEntry( cc->second );
504 * \brief adds a new Patient (with the basic elements) to a partially created DICOMDIR
506 gdcmDicomDirPatient * gdcmDicomDir::NewPatient()
508 std::list<gdcmElement>::iterator it;
509 uint16_t tmpGr,tmpEl;
510 gdcmDictEntry *dictEntry;
513 std::list<gdcmElement> elemList;
514 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirPatientElements();
515 // Looks nice, but gdcmDicomDir IS NOT a gdcmObject ...
516 // gdcmDicomDirPatient *p = new gdcmDicomDirPatient(ptagHT);
517 // FillObject(elemList);
518 // patients.push_front( p );
520 /// \todo TODO : find a trick to use FillObject !!!
522 gdcmSQItem *s = new gdcmSQItem(0);
524 // for all the DicomDirPatient Elements
525 for( it = elemList.begin(); it != elemList.end(); ++it )
529 dictEntry = GetPubDict()->GetDictEntryByNumber(tmpGr, tmpEl);
530 entry = new gdcmValEntry( dictEntry );
531 entry->SetOffset(0); // just to avoid further missprinting
532 entry->SetValue( it->value );
534 // dealing with value length ...
536 if( dictEntry->GetGroup() == 0xfffe)
538 entry->SetLength(entry->GetValue().length());
540 else if( dictEntry->GetVR() == "UL" || dictEntry->GetVR() == "SL" )
542 entry->SetLength( 4 );
544 else if( dictEntry->GetVR() == "US" || dictEntry->GetVR() == "SS" )
548 else if( dictEntry->GetVR() == "SQ" )
550 entry->SetLength( 0xffffffff );
554 entry->SetLength( entry->GetValue().length() );
556 s->AddDocEntry( entry );
559 gdcmDicomDirPatient *p = new gdcmDicomDirPatient(s, &TagHT);
560 patients.push_front( p );
566 * \brief adds to the HTable
567 * the gdcmEntries (Dicom Elements) corresponding to the given type
568 * @param path full path file name (only used when type = GDCM_DICOMDIR_IMAGE
569 * @param type gdcmObject type to create (GDCM_DICOMDIR_PATIENT,
570 * GDCM_DICOMDIR_STUDY, GDCM_DICOMDIR_SERIE ...)
571 * @param header gdcmHeader of the current file
573 void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,
574 gdcmDocument *header)
576 std::list<gdcmElement> elemList;
577 std::list<gdcmElement>::iterator it;
578 uint16_t tmpGr, tmpEl;
579 gdcmDictEntry *dictEntry;
585 case GDCM_DICOMDIR_IMAGE:
586 elemList = gdcmGlobal::GetDicomDirElements()->GetDicomDirImageElements();
589 case GDCM_DICOMDIR_SERIE:
590 elemList = gdcmGlobal::GetDicomDirElements()->GetDicomDirSerieElements();
593 case GDCM_DICOMDIR_STUDY:
594 elemList = gdcmGlobal::GetDicomDirElements()->GetDicomDirStudyElements();
597 case GDCM_DICOMDIR_PATIENT:
598 elemList = gdcmGlobal::GetDicomDirElements()->GetDicomDirPatientElements();
601 case GDCM_DICOMDIR_META:
602 elemList = gdcmGlobal::GetDicomDirElements()->GetDicomDirMetaElements();
609 for( it = elemList.begin(); it != elemList.end(); ++it)
613 dictEntry = GetPubDict()->GetDictEntryByNumber(tmpGr, tmpEl);
614 entry = new gdcmValEntry( dictEntry ); // Be sure it's never a BinEntry !
616 entry->SetOffset(0); // just to avoid further missprinting
618 if( header ) // NULL when we Build Up (ex nihilo) a DICOMDIR
619 // or when we add the META elems
621 val = header->GetEntryByNumber(tmpGr, tmpEl);
628 if( val == GDCM_UNFOUND)
630 if( tmpGr == 0x0004 && tmpEl == 0x1130 ) // File-set ID
632 // force to the *end* File Name
633 val = GetName( path );
635 else if( tmpGr == 0x0004 && tmpEl == 0x1500 ) // Only used for image
637 if( header->GetFileName().substr(0, path.length()) != path )
639 dbg.Verbose(0, "gdcmDicomDir::SetElement : the base path"
640 " of file name is incorrect");
641 val = header->GetFileName();
645 val = &(header->GetFileName().c_str()[path.length()]);
655 if ( header->GetEntryLengthByNumber(tmpGr,tmpEl) == 0 )
661 entry->SetValue( val );
665 if( dictEntry->GetGroup() == 0xfffe )
667 entry->SetLength( entry->GetValue().length() ); // FIXME
669 else if( dictEntry->GetVR() == "UL" || dictEntry->GetVR() == "SL" )
673 else if( dictEntry->GetVR() == "US" || dictEntry->GetVR() == "SS" )
677 else if( dictEntry->GetVR() == "SQ" )
679 entry->SetLength( 0xffffffff );
683 entry->SetLength( entry->GetValue().length() );
686 std::cout << " was TagHT[entry->GetKey()] = entry " << std::endl;
687 if ( type == GDCM_DICOMDIR_META ) {
688 std::cout << " special Treatment for GDCM_DICOMDIR_META" << std::endl;
691 //TagHT[entry->GetKey()] = entry; // FIXME : use a SEQUENCE !
696 * \brief CallStartMethod
698 void gdcmDicomDir::CallStartMethod()
704 startMethod( startArg );
709 * \ingroup gdcmDicomDir
710 * \brief CallProgressMethod
712 void gdcmDicomDir::CallProgressMethod()
716 progressMethod( progressArg );
721 * \ingroup gdcmDicomDir
722 * \brief CallEndMethod
724 void gdcmDicomDir::CallEndMethod()
733 //-----------------------------------------------------------------------------
736 * \ingroup gdcmDicomDir
737 * \brief create a 'gdcmDicomDir' from a DICOMDIR gdcmHeader
739 void gdcmDicomDir::CreateDicomDir()
741 // The list is parsed.
742 // When a DicomDir tag ("PATIENT", "STUDY", "SERIE", "IMAGE") is found :
743 // 1 - we save the beginning iterator
744 // 2 - we continue to parse
745 // 3 - we find an other tag
746 // + we create the object for the precedent tag
749 // Directory record sequence
750 gdcmDocEntry *e = GetDocEntryByNumber(0x0004, 0x1220);
753 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : NO Directory record"
754 " sequence (0x0004,0x1220)");
755 /// \todo FIXME: what to do when the parsed file IS NOT a DICOMDIR file ?
759 gdcmSeqEntry* s = dynamic_cast<gdcmSeqEntry*>(e);
762 dbg.Verbose(0, "gdcmDicomDir::CreateDicomDir: no SeqEntry present");
763 // useless : (0x0004,0x1220) IS a Sequence !
767 gdcmDicomDirType type = gdcmDicomDir::GDCM_DICOMDIR_META;
768 metaElems = NewMeta();
770 ListSQItem listItems = s->GetSQItems();
774 for( ListSQItem::iterator i = listItems.begin();
775 i !=listItems.end(); ++i )
777 d = (*i)->GetDocEntryByNumber(0x0004, 0x1430); // Directory Record Type
778 if ( gdcmValEntry* ValEntry = dynamic_cast< gdcmValEntry* >(d) )
780 v = ValEntry->GetValue();
784 dbg.Verbose(0, "gdcmDicomDir::CreateDicomDir: not a ValEntry.");
788 if( v == "PATIENT " )
790 AddDicomDirPatientToEnd( *i );
791 //AddObjectToEnd(type,*i);
792 type = gdcmDicomDir::GDCM_DICOMDIR_PATIENT;
794 else if( v == "STUDY " )
796 AddDicomDirStudyToEnd( *i );
797 // AddObjectToEnd(type,*i);
798 type = gdcmDicomDir::GDCM_DICOMDIR_STUDY;
800 else if( v == "SERIES" )
802 AddDicomDirSerieToEnd( *i );
803 // AddObjectToEnd(type,*i);
804 type = gdcmDicomDir::GDCM_DICOMDIR_SERIE;
806 else if( v == "IMAGE " )
808 AddDicomDirImageToEnd( *i );
809 // AddObjectToEnd(type,*i);
810 type = gdcmDicomDir::GDCM_DICOMDIR_IMAGE;
814 // It was not a 'PATIENT', nor a 'STUDY', nor a 'SERIE',
815 // neither an 'IMAGE' SQItem. Skip to next item.
822 * \ingroup gdcmDicomDir
823 * \brief AddObjectToEnd
825 * @param begin iterator on the first DocEntry within the chained List
826 * @param end iterator on the last DocEntry within the chained List
831 /*void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,gdcmSQItem *s)
838 case gdcmDicomDir::GDCM_DICOMDIR_META:
841 case gdcmDicomDir::GDCM_DICOMDIR_PATIENT:
842 AddDicomDirPatientToEnd(s);
844 case gdcmDicomDir::GDCM_DICOMDIR_STUDY:
845 AddDicomDirStudyToEnd(s);
847 case gdcmDicomDir::GDCM_DICOMDIR_SERIE:
848 AddDicomDirSerieToEnd(s);
850 case gdcmDicomDir::GDCM_DICOMDIR_IMAGE:
851 AddDicomDirImageToEnd(s);
853 case gdcmDicomDir::GDCM_DICOMDIR_NONE:
854 AddDicomDirImageToEnd(s); //FIXME
862 * \ingroup gdcmDicomDir
863 * \brief Well ... there is only one occurence
865 void gdcmDicomDir::AddDicomDirMeta()
871 metaElems = new gdcmDicomDirMeta( &TagHT );
875 * \ingroup gdcmDicomDir
876 * \brief AddDicomDirPatientToEnd
877 * @param s SQ Item to enqueue to the DicomPatient chained List
879 void gdcmDicomDir::AddDicomDirPatientToEnd(gdcmSQItem *s)
881 patients.push_back(new gdcmDicomDirPatient(s, &TagHT));
885 * \ingroup gdcmDicomDir
886 * \brief AddDicomDirStudyToEnd
887 * @param s SQ Item to enqueue to the DicomDirStudy chained List
889 void gdcmDicomDir::AddDicomDirStudyToEnd(gdcmSQItem *s)
891 if( patients.size() > 0 )
893 ListDicomDirPatient::iterator itp = patients.end();
895 (*itp)->AddDicomDirStudy(new gdcmDicomDirStudy(s, &TagHT));
900 * \ingroup gdcmDicomDir
901 * \brief AddDicomDirSerieToEnd
902 * @param s SQ Item to enqueue to the DicomDirSerie chained List
904 void gdcmDicomDir::AddDicomDirSerieToEnd(gdcmSQItem *s)
906 if( patients.size() > 0 )
908 ListDicomDirPatient::iterator itp = patients.end();
911 if( (*itp)->GetDicomDirStudies().size() > 0 )
913 ListDicomDirStudy::iterator itst=(*itp)->GetDicomDirStudies().end();
915 (*itst)->AddDicomDirSerie(new gdcmDicomDirSerie(s, &TagHT));
921 * \ingroup gdcmDicomDir
922 * \brief AddDicomDirImageToEnd
923 * @param s SQ Item to enqueue to the DicomDirImage chained List
925 void gdcmDicomDir::AddDicomDirImageToEnd(gdcmSQItem *s)
927 if( patients.size() > 0 )
929 ListDicomDirPatient::iterator itp = patients.end();
932 if( (*itp)->GetDicomDirStudies().size() > 0 )
934 ListDicomDirStudy::iterator itst = (*itp)->GetDicomDirStudies().end();
937 if( (*itst)->GetDicomDirSeries().size() > 0 )
939 ListDicomDirSerie::iterator its = (*itst)->GetDicomDirSeries().end();
941 (*its)->AddDicomDirImage(new gdcmDicomDirImage(s, &TagHT));
948 * \ingroup gdcmDicomDir
949 * \brief for each Header of the chained list, add/update the Patient/Study/Serie/Image info
950 * @param path path of the root directory
951 * @param list chained list of Headers
953 void gdcmDicomDir::SetElements(std::string &path, VectDocument &list)
955 std::string patPrevName = "", patPrevID = "";
956 std::string studPrevInstanceUID = "", studPrevID = "";
957 std::string serPrevInstanceUID = "", serPrevID = "";
959 std::string patCurName, patCurID;
960 std::string studCurInstanceUID, studCurID;
961 std::string serCurInstanceUID, serCurID;
963 SetElement( path, GDCM_DICOMDIR_META,NULL);
965 for( VectDocument::iterator it = list.begin();
966 it != list.end(); ++it )
968 // get the current file characteristics
969 patCurName = (*it)->GetEntryByNumber(0x0010,0x0010);
970 patCurID = (*it)->GetEntryByNumber(0x0010,0x0011);
971 studCurInstanceUID = (*it)->GetEntryByNumber(0x0020,0x000d);
972 studCurID = (*it)->GetEntryByNumber(0x0020,0x0010);
973 serCurInstanceUID = (*it)->GetEntryByNumber(0x0020,0x000e);
974 serCurID = (*it)->GetEntryByNumber(0x0020,0x0011);
976 if( patCurName != patPrevName || patCurID != patPrevID)
978 SetElement(path, GDCM_DICOMDIR_PATIENT, *it);
981 // if new Study Deal with 'STUDY' Elements
982 if( studCurInstanceUID != studPrevInstanceUID || studCurID != studPrevID )
984 SetElement(path, GDCM_DICOMDIR_STUDY, *it);
987 // if new Serie Deal with 'SERIE' Elements
988 if( serCurInstanceUID != serPrevInstanceUID || serCurID != serPrevID )
990 SetElement(path, GDCM_DICOMDIR_SERIE, *it);
993 // Always Deal with 'IMAGE' Elements
994 SetElement(path, GDCM_DICOMDIR_IMAGE, *it);
996 patPrevName = patCurName;
997 patPrevID = patCurID;
998 studPrevInstanceUID = studCurInstanceUID;
999 studPrevID = studCurID;
1000 serPrevInstanceUID = serCurInstanceUID;
1001 serPrevID = serCurID;
1006 * \ingroup gdcmDicomDir
1007 * \brief compares two dgcmHeaders
1009 bool gdcmDicomDir::HeaderLessThan(gdcmDocument *header1, gdcmDocument *header2)
1011 return *header1 < *header2;
1015 * \brief Sets the accurate value for the (0x0004,0x1220) element of a DICOMDIR
1017 void gdcmDicomDir::UpdateDirectoryRecordSequenceLength()
1020 /// \todo FIXME : to go on compiling
1022 /// to be re written !
1024 /// ListTag::iterator it;
1025 /// uint16_t gr, el;
1027 /// for(it=listEntries.begin();it!=listEntries.end();++it) {
1028 /// gr = (*it)->GetGroup();
1029 /// el = (*it)->GetElement();
1030 /// vr = (*it)->GetVR();
1031 /// if (gr !=0xfffe) {
1032 /// if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ) {
1033 /// offset += 4; // explicit VR AND OB, OW, SQ : 4 more bytes
1035 /// offset += 2 + 2 + 4 + (*it)->GetLength();
1037 /// offset += 4; // delimiters don't have a value.
1040 /// //bool res=SetEntryLengthByNumber(offset, 0x0004, 0x1220); // Hope there is no dupps.
1041 /// SetEntryLengthByNumber(offset, 0x0004, 0x1220); // Hope there is no dupps.
1046 //-----------------------------------------------------------------------------