2 //-----------------------------------------------------------------------------
14 #include "gdcmDicomDir.h"
15 #include "gdcmDicomDirStudy.h"
16 #include "gdcmDicomDirSerie.h"
17 #include "gdcmDicomDirImage.h"
18 #include "gdcmDirList.h"
20 #include "gdcmDebug.h"
21 #include "gdcmGlobal.h"
23 #include "gdcmSeqEntry.h"
24 #include "gdcmSQItem.h"
25 #include "gdcmValEntry.h"
27 //-----------------------------------------------------------------------------
28 // For full DICOMDIR description, see:
29 // PS 3.3-2003, pages 731-750
30 //-----------------------------------------------------------------------------
33 // Constructor / Destructor
36 * \brief Constructor Parses recursively the directory and creates the DicomDir
37 * or uses an already built DICOMDIR, depending on 'parseDir' value.
38 * @param FileName name
39 * - of the root directory (parseDir = true)
40 * - of the DICOMDIR (parseDir = false)
41 * @param parseDir boolean
42 * - true if user passed an entry point
43 * and wants to explore recursively the directories
44 * - false if user passed an already built DICOMDIR file
46 * @param exception_on_error whether we want to throw an exception or not
48 gdcmDicomDir::gdcmDicomDir(const char *FileName, bool parseDir,
49 bool exception_on_error):
50 gdcmDocument(FileName,exception_on_error,true) // true : enable SeQuences
52 // que l'on ai passe un root directory ou un DICOMDIR
53 // et quelle que soit la valeur de parseDir,
54 // on a lance gdcmDocument
59 startMethodArgDelete= NULL;
60 progressMethodArgDelete=NULL;
61 endMethodArgDelete= NULL;
71 // gdcmDocument already executed
72 // if user passed a root directory, sure we didn't get anything
74 if( GetEntry().begin()==GetEntry().end() )
76 // if parseDir == false, it should be tagged as an error
77 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : entry HT empty");
79 if(strlen(FileName)==1 && FileName[0]=='.') { // user passed '.' as Name
80 // we get current directory name
81 char* dummy= new char[1000];
82 getcwd(dummy, (size_t)1000);
83 SetFileName(dummy); // will be converted into a string
84 delete[] dummy; // no longer needed
89 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory"
90 " and create the DicomDir");
95 gdcmDocEntry *e = GetDocEntryByNumber(0x0004, 0x1220); // Directory record sequence
97 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : NO Directory record sequence (0x0004,0x1220)"
99 // FIXME : what to do when the parsed file IS NOT a DICOMDIR file ?
106 * \ingroup gdcmDicomDir
107 * \brief Constructor : creates an empty gdcmDicomDir
108 * @param exception_on_error whether we want to throw an exception or not
110 gdcmDicomDir::gdcmDicomDir(bool exception_on_error):
111 gdcmDocument(exception_on_error)
114 progressMethod= NULL;
116 startMethodArgDelete= NULL;
117 progressMethodArgDelete=NULL;
118 endMethodArgDelete= NULL;
124 std::string pathBidon = ""; // Sorry, NULL not allowed ...
125 SetElement(pathBidon, GDCM_DICOMDIR_META, NULL); // Set the META elements
131 * \ingroup gdcmDicomDir
132 * \brief Canonical destructor
134 gdcmDicomDir::~gdcmDicomDir()
136 SetStartMethod(NULL);
137 SetProgressMethod(NULL);
143 for(ListDicomDirPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
149 //-----------------------------------------------------------------------------
152 * \ingroup gdcmDicomDir
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();cc!=patients.end();++cc)
164 (*cc)->SetPrintLevel(printLevel);
169 //-----------------------------------------------------------------------------
172 * \ingroup gdcmDicomDir
173 * \brief This predicate, based on hopefully reasonable heuristics,
174 * decides whether or not the current header was properly parsed
175 * and contains the mandatory information for being considered as
176 * a well formed and usable DicomDir.
177 * @return true when gdcmDocument is the one of a reasonable DicomDir,
180 bool gdcmDicomDir::IsReadable(void)
182 if(!gdcmDocument::IsReadable())
186 if(patients.size()<=0)
193 * \ingroup gdcmDicomDir
194 * \brief fills the whole structure, starting from a root Directory
196 void gdcmDicomDir::ParseDirectory(void)
198 CreateDicomDirChainedList(GetFileName());
203 * \ingroup gdcmDicomDir
204 * \brief Set the start method to call when the parsing of the directory starts
205 * @param method Method to call
206 * @param arg Argument to pass to the method
207 * @param argDelete Argument
208 * \warning In python : the arg parameter isn't considered
210 void gdcmDicomDir::SetStartMethod(gdcmMethod *method,void *arg,gdcmMethod *argDelete)
212 if((startArg)&&(startMethodArgDelete))
213 startMethodArgDelete(startArg);
217 startMethodArgDelete=argDelete;
221 * \ingroup gdcmDicomDir
222 * \brief Set the method to delete the argument
223 * The argument is destroyed when the method is changed or when the
225 * @param method Method to call to delete the argument
227 void gdcmDicomDir::SetStartMethodArgDelete(gdcmMethod *method)
229 startMethodArgDelete=method;
233 * \ingroup gdcmDicomDir
234 * \brief Set the progress method to call when the parsing of the directory progress
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::SetProgressMethod(gdcmMethod *method,void *arg,gdcmMethod *argDelete)
242 if((progressArg)&&(progressMethodArgDelete))
243 progressMethodArgDelete(progressArg);
245 progressMethod=method;
247 progressMethodArgDelete=argDelete;
251 * \ingroup gdcmDicomDir
252 * \brief Set the method to delete the argument
253 * The argument is destroyed when the method is changed or when the
255 * @param method Method to call to delete the argument
257 void gdcmDicomDir::SetProgressMethodArgDelete(gdcmMethod *method)
259 progressMethodArgDelete=method;
263 * \ingroup gdcmDicomDir
264 * \brief Set the end method to call when the parsing of the directory ends
265 * @param method Method to call
266 * @param arg Argument to pass to the method
267 * @param argDelete Argument
268 * \warning In python : the arg parameter isn't considered
270 void gdcmDicomDir::SetEndMethod(gdcmMethod *method, void *arg, gdcmMethod *argDelete)
272 if((endArg)&&(endMethodArgDelete))
273 endMethodArgDelete(endArg);
277 endMethodArgDelete=argDelete;
281 * \ingroup gdcmDicomDir
282 * \brief Set the method to delete the argument
283 * The argument is destroyed when the method is changed or when the class
285 * @param method Method to call to delete the argument
287 void gdcmDicomDir::SetEndMethodArgDelete(gdcmMethod *method)
289 endMethodArgDelete=method;
293 * \ingroup gdcmDicomDir
294 * \brief writes on disc a DICOMDIR
295 * \ warning does NOT add the missing elements in the header :
296 * it's up to the user doing it !
297 * \todo : to be re-written using the DICOMDIR tree-like structure
298 * *not* the chained list
299 * (does NOT exist if the DICOMDIR is user-forged !)
300 * @param fileName file to be written to
301 * @return false only when fail to open
304 bool gdcmDicomDir::Write(std::string fileName)
308 fp1=fopen(fileName.c_str(),"wb");
311 printf("Failed to open(write) File [%s] \n",fileName.c_str());
315 char * filePreamble = new char[128];
316 fwrite(filePreamble,128,1,fp1);
317 fwrite("DICM",4,1,fp1);
318 delete[] filePreamble;
319 UpdateDirectoryRecordSequenceLength();
327 * \brief Writes in a file using the tree-like structure.
328 * @param _fp already open file pointer
331 void gdcmDicomDir::WriteEntries(FILE *_fp)
333 /// \todo (?) tester les echecs en ecriture
334 /// (apres chaque fwrite, dans le WriteEntry)
337 /* TODO : to go on compiling
339 gdcmDicomDirMeta *ptrMeta;
340 ListDicomDirPatient::iterator itPatient;
341 ListDicomDirStudy::iterator itStudy;
342 ListDicomDirSerie::iterator itSerie;
343 ListDicomDirImage::iterator itImage;
346 ptrMeta= GetDicomDirMeta();
347 for(i=ptrMeta->debut();i!=ptrMeta->fin();++i) {
348 WriteEntry(*i,_fp, gdcmExplicitVR);
351 itPatient = GetDicomDirPatients().begin();
352 while ( itPatient != GetDicomDirPatients().end() ) {
353 for(i=(*itPatient)->debut();i!=(*itPatient)->fin();++i) {
354 WriteEntry(*i,_fp, gdcmExplicitVR);
356 itStudy = ((*itPatient)->GetDicomDirStudies()).begin();
357 while (itStudy != (*itPatient)->GetDicomDirStudies().end() ) {
358 for(i=(*itStudy)->debut();i!=(*itStudy)->fin();++i) {
359 WriteEntry(*i,_fp, gdcmExplicitVR);
361 itSerie = ((*itStudy)->GetDicomDirSeries()).begin();
362 while (itSerie != (*itStudy)->GetDicomDirSeries().end() ) {
363 for(i=(*itSerie)->debut();i!=(*itSerie)->fin();++i) {
364 WriteEntry(*i,_fp, gdcmExplicitVR);
366 itImage = ((*itSerie)->GetDicomDirImages()).begin();
367 while (itImage != (*itSerie)->GetDicomDirImages().end() ) {
368 for(i=(*itImage)->debut();i!=(*itImage)->fin();++i) {
369 WriteEntry(*i,_fp, gdcmExplicitVR);
382 //-----------------------------------------------------------------------------
386 * \ingroup gdcmDicomDir
387 * \brief create a gdcmDocument-like chained list from a root Directory
388 * @param path entry point of the tree-like structure
390 void gdcmDicomDir::CreateDicomDirChainedList(std::string path)
394 gdcmDirList fileList(path,1); // gets recursively the file list
395 unsigned int count=0;
402 for(gdcmDirList::iterator it=fileList.begin();
406 progress=(float)(count+1)/(float)fileList.size();
407 CallProgressMethod();
411 header=new gdcmHeader(it->c_str());
412 if(header->IsReadable())
413 list.push_back(header); // adds the file header to the chained list
419 // sorts Patient/Study/Serie/
420 std::sort(list.begin(),list.end(),gdcmDicomDir::HeaderLessThan);
422 std::string tmp=fileList.GetDirName();
424 //for each Header of the chained list, add/update the Patient/Study/Serie/Image info
425 SetElements(tmp,list);
431 * \ingroup gdcmDicomDir
432 * \brief adds *the* Meta to a partially created DICOMDIR
435 // FIXME : Heuuuuu ! Il prend les Entries du Document deja parse,
436 // il ne fabrique rien !
438 gdcmDicomDirMeta * gdcmDicomDir::NewMeta(void) {
439 gdcmDicomDirMeta *m = new gdcmDicomDirMeta(&tagHT);
440 for (TagDocEntryHT::iterator cc = tagHT.begin();cc != tagHT.end();++cc) {
441 m->AddDocEntry(cc->second);
448 * \ingroup gdcmDicomDir
449 * \brief adds a new Patient (with the basic elements) to a partially created DICOMDIR
451 gdcmDicomDirPatient * gdcmDicomDir::NewPatient(void) {
452 std::list<gdcmElement> elemList;
453 std::list<gdcmElement>::iterator it;
455 gdcmDictEntry *dictEntry;
458 gdcmSQItem *s = new gdcmSQItem(0);
460 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirPatientElements();
462 // TODO : use FillObject !!!
464 // for all the DicomDirPatient Elements
466 for(it=elemList.begin();it!=elemList.end();++it)
470 dictEntry=GetPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
471 entry=new gdcmValEntry(dictEntry);
472 entry->SetOffset(0); // just to avoid further missprinting
473 entry->SetValue(it->value);
475 // dealing with value length ...
477 if(dictEntry->GetGroup()==0xfffe)
479 entry->SetLength(entry->GetValue().length());
481 else if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") )
485 else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") )
489 else if(dictEntry->GetVR()=="SQ")
491 entry->SetLength(0xffffffff);
495 entry->SetLength(entry->GetValue().length());
497 s->AddDocEntry(entry);
500 gdcmDicomDirPatient *p = new gdcmDicomDirPatient(s, &tagHT);
501 patients.push_front(p);
507 * \ingroup gdcmDicomDir
508 * \brief adds to the HTable
509 * the gdcmEntries (Dicom Elements) corresponding to the given type
510 * @param path full path file name (only used when type = GDCM_DICOMDIR_IMAGE
511 * @param type gdcmObject type to create (GDCM_DICOMDIR_PATIENT, GDCM_DICOMDIR_STUDY, GDCM_DICOMDIR_SERIE ...)
512 * @param header gdcmHeader of the current file
514 void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader *header)
516 std::list<gdcmElement> elemList;
517 std::list<gdcmElement>::iterator it;
518 guint16 tmpGr, tmpEl;
519 gdcmDictEntry *dictEntry;
525 case GDCM_DICOMDIR_PATIENT:
526 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirPatientElements();
528 case GDCM_DICOMDIR_STUDY:
529 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirStudyElements();
531 case GDCM_DICOMDIR_SERIE:
532 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirSerieElements();
534 case GDCM_DICOMDIR_IMAGE:
535 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirImageElements();
537 case GDCM_DICOMDIR_META:
538 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirMetaElements();
544 for(it=elemList.begin();it!=elemList.end();++it)
548 dictEntry=GetPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
549 entry=new gdcmDocEntry(dictEntry);
550 entry->SetOffset(0); // just to avoid further missprinting
553 val=header->GetEntryByNumber(tmpGr,tmpEl);
557 if(val==GDCM_UNFOUND)
559 if((tmpGr==0x0004) &&(tmpEl==0x1130) ) // File-set ID
561 // force to the *end* File Name
564 else if( (tmpGr==0x0004) && (tmpEl==0x1500) ) // Only used for image
566 if(header->GetFileName().substr(0,path.length())!=path)
568 dbg.Verbose(0, "gdcmDicomDir::SetElement : the base path of file name is incorrect");
569 val=header->GetFileName();
572 val=&(header->GetFileName().c_str()[path.length()]);
582 if (header->GetEntryLengthByNumber(tmpGr,tmpEl)== 0)
586 ((gdcmValEntry *)entry)->SetValue(val);
590 if(dictEntry->GetGroup()==0xfffe)
592 entry->SetLength(((gdcmValEntry *)entry)->GetValue().length());
594 else if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") )
598 else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") )
602 else if(dictEntry->GetVR()=="SQ")
604 entry->SetLength(0xffffffff);
608 entry->SetLength(((gdcmValEntry *)entry)->GetValue().length());
611 //AddDocEntry(entry); // both in H Table and in chained list
612 tagHT[entry->GetKey()] = entry; // FIXME : use a SEQUENCE !
616 * \ingroup gdcmDicomDir
617 * \brief CallStartMethod
619 void gdcmDicomDir::CallStartMethod(void)
624 startMethod(startArg);
627 * \ingroup gdcmDicomDir
628 * \brief CallProgressMethod
630 void gdcmDicomDir::CallProgressMethod(void)
633 progressMethod(progressArg);
636 * \ingroup gdcmDicomDir
637 * \brief CallEndMethod
639 void gdcmDicomDir::CallEndMethod(void)
646 //-----------------------------------------------------------------------------
649 * \ingroup gdcmDicomDir
650 * \brief create a 'gdcmDicomDir' from a DICOMDIR gdcmHeader
652 void gdcmDicomDir::CreateDicomDir()
654 // The list is parsed.
655 // When a DicomDir tag ("PATIENT", "STUDY", "SERIE", "IMAGE") is found :
656 // 1 - we save the beginning iterator
657 // 2 - we continue to parse
658 // 3 - we find an other tag
659 // + we create the object for the precedent tag
662 gdcmDicomDirType type=gdcmDicomDir::GDCM_DICOMDIR_META;
664 gdcmDocEntry *e = GetDocEntryByNumber(0x0004, 0x1220); // Directory record sequence
666 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : NO Directory record sequence (0x0004,0x1220)"
668 // FIXME : what to do when the parsed file IS NOT a DICOMDIR file ?
672 gdcmDicomDirMeta *m = new gdcmDicomDirMeta(&tagHT);
674 gdcmSeqEntry *s = (gdcmSeqEntry *)e; // FIXME : It is allowed ???
675 ListSQItem listItems = s->GetSQItems();
678 for(ListSQItem::iterator i=listItems.begin(); i !=listItems.end();++i)
680 d=(*i)->GetDocEntryByNumber(0x0004, 0x1430); // Directory Record Type
681 std::string v=((gdcmValEntry *)d)->GetValue();
685 AddDicomDirPatientToEnd(*i);
686 //AddObjectToEnd(type,*i);
687 type=gdcmDicomDir::GDCM_DICOMDIR_PATIENT;
692 AddDicomDirStudyToEnd(*i);
693 // AddObjectToEnd(type,*i);
694 type=gdcmDicomDir::GDCM_DICOMDIR_STUDY;
699 AddDicomDirSerieToEnd(*i);
700 // AddObjectToEnd(type,*i);
701 type=gdcmDicomDir::GDCM_DICOMDIR_SERIE;
706 AddDicomDirImageToEnd(*i);
707 // AddObjectToEnd(type,*i);
708 type=gdcmDicomDir::GDCM_DICOMDIR_IMAGE;
712 continue ; // It was 'non PATIENT', 'non STUDY', 'non SERIE', 'non IMAGE' SQItem
716 * \ingroup gdcmDicomDir
717 * \brief AddObjectToEnd
719 * @param begin iterator on the first DocEntry within the chained List
720 * @param end iterator on the last DocEntry within the chained List
725 /*void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,gdcmSQItem *s)
732 case gdcmDicomDir::GDCM_DICOMDIR_META:
735 case gdcmDicomDir::GDCM_DICOMDIR_PATIENT:
736 AddDicomDirPatientToEnd(s);
738 case gdcmDicomDir::GDCM_DICOMDIR_STUDY:
739 AddDicomDirStudyToEnd(s);
741 case gdcmDicomDir::GDCM_DICOMDIR_SERIE:
742 AddDicomDirSerieToEnd(s);
744 case gdcmDicomDir::GDCM_DICOMDIR_IMAGE:
745 AddDicomDirImageToEnd(s);
747 case gdcmDicomDir::GDCM_DICOMDIR_NONE:
748 AddDicomDirImageToEnd(s); //FIXME
756 * \ingroup gdcmDicomDir
757 * \brief Well ... there is only one occurence
759 void gdcmDicomDir::AddDicomDirMeta()
763 metaElems = new gdcmDicomDirMeta(&tagHT);
767 * \ingroup gdcmDicomDir
768 * \brief AddDicomDirPatientToEnd
769 * @param s SQ Item to enqueue to the DicomPatient chained List
771 void gdcmDicomDir::AddDicomDirPatientToEnd(gdcmSQItem *s)
773 patients.push_back(new gdcmDicomDirPatient(s, &tagHT));
777 * \ingroup gdcmDicomDir
778 * \brief AddDicomDirStudyToEnd
779 * @param s SQ Item to enqueue to the DicomDirStudy chained List
781 void gdcmDicomDir::AddDicomDirStudyToEnd(gdcmSQItem *s)
783 if(patients.size()>0)
785 ListDicomDirPatient::iterator itp=patients.end();
787 (*itp)->AddDicomDirStudy(new gdcmDicomDirStudy(s, &tagHT));
791 * \ingroup gdcmDicomDir
792 * \brief AddDicomDirSerieToEnd
793 * @param s SQ Item to enqueue to the DicomDirSerie chained List
795 void gdcmDicomDir::AddDicomDirSerieToEnd(gdcmSQItem *s)
797 if(patients.size()>0)
799 ListDicomDirPatient::iterator itp=patients.end();
802 if((*itp)->GetDicomDirStudies().size()>0)
804 ListDicomDirStudy::iterator itst=(*itp)->GetDicomDirStudies().end();
806 (*itst)->AddDicomDirSerie(new gdcmDicomDirSerie(s, &tagHT));
812 * \ingroup gdcmDicomDir
813 * \brief AddDicomDirImageToEnd
814 * @param s SQ Item to enqueue to the DicomDirImage chained List
816 void gdcmDicomDir::AddDicomDirImageToEnd(gdcmSQItem *s)
818 if(patients.size()>0)
820 ListDicomDirPatient::iterator itp=patients.end();
823 if((*itp)->GetDicomDirStudies().size()>0)
825 ListDicomDirStudy::iterator itst=(*itp)->GetDicomDirStudies().end();
828 if((*itst)->GetDicomDirSeries().size()>0)
830 ListDicomDirSerie::iterator its=(*itst)->GetDicomDirSeries().end();
832 (*its)->AddDicomDirImage(new gdcmDicomDirImage(s, &tagHT));
839 * \ingroup gdcmDicomDir
840 * \brief for each Header of the chained list, add/update the Patient/Study/Serie/Image info
841 * @param path path of the root directory
842 * @param list chained list of Headers
844 void gdcmDicomDir::SetElements(std::string &path, ListHeader &list)
846 std::string patPrevName="", patPrevID="";
847 std::string studPrevInstanceUID="", studPrevID="";
848 std::string serPrevInstanceUID="", serPrevID="";
850 std::string patCurName, patCurID;
851 std::string studCurInstanceUID, studCurID;
852 std::string serCurInstanceUID, serCurID;
854 SetElement(path,GDCM_DICOMDIR_META,NULL);
856 for(ListHeader::iterator it=list.begin();it!=list.end();++it)
858 // get the current file characteristics
859 patCurName= (*it)->GetEntryByNumber(0x0010,0x0010);
860 patCurID= (*it)->GetEntryByNumber(0x0010,0x0011);
861 studCurInstanceUID=(*it)->GetEntryByNumber(0x0020,0x000d);
862 studCurID= (*it)->GetEntryByNumber(0x0020,0x0010);
863 serCurInstanceUID= (*it)->GetEntryByNumber(0x0020,0x000e);
864 serCurID= (*it)->GetEntryByNumber(0x0020,0x0011);
866 if(patCurName!=patPrevName || patCurID!=patPrevID)
867 SetElement(path,GDCM_DICOMDIR_PATIENT,*it);
869 // if new Study Deal with 'STUDY' Elements
870 if(studCurInstanceUID!=studPrevInstanceUID || studCurID!=studPrevID)
871 SetElement(path,GDCM_DICOMDIR_STUDY,*it);
873 // if new Serie Deal with 'SERIE' Elements
874 if(serCurInstanceUID!=serPrevInstanceUID || serCurID!=serPrevID)
875 SetElement(path,GDCM_DICOMDIR_SERIE,*it);
877 // Always Deal with 'IMAGE' Elements
878 SetElement(path,GDCM_DICOMDIR_IMAGE,*it);
880 patPrevName= patCurName;
882 studPrevInstanceUID=studCurInstanceUID;
883 studPrevID= studCurID;
884 serPrevInstanceUID= serCurInstanceUID;
890 * \ingroup gdcmDicomDir
891 * \brief compares two dgcmHeaders
893 bool gdcmDicomDir::HeaderLessThan(gdcmHeader *header1,gdcmHeader *header2)
895 return(*header1<*header2);
899 * \ingroup gdcmDicomDir
900 * \brief Sets the accurate value for the (0x0004,0x1220) element of a DICOMDIR
903 void gdcmDicomDir::UpdateDirectoryRecordSequenceLength() {
905 // FIXME : to go on compiling
907 // to be re written !
910 ListTag::iterator it;
913 for(it=listEntries.begin();it!=listEntries.end();++it) {
914 gr = (*it)->GetGroup();
915 el = (*it)->GetElement();
918 if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ) {
919 offset += 4; // explicit VR AND OB, OW, SQ : 4 more bytes
921 offset += 2 + 2 + 4 + (*it)->GetLength();
923 offset += 4; // delimiters don't have a value.
926 //bool res=SetEntryLengthByNumber(offset, 0x0004, 0x1220); // Hope there is no dupps.
927 SetEntryLengthByNumber(offset, 0x0004, 0x1220); // Hope there is no dupps.
932 //-----------------------------------------------------------------------------