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"
22 //-----------------------------------------------------------------------------
23 // For full DICOMDIR description, see:
24 // PS 3.3-2003, pages 731-750
25 //-----------------------------------------------------------------------------
27 // Constructor / Destructor
30 * \ingroup gdcmDicomDir
31 * \brief Constructor Parses recursively the directory and creates the DicomDir
32 * or uses an already built DICOMDIR, depending on 'parseDir' value
33 * @param FileName name
34 - of the root directory (parseDir = true)
35 * - of the DICOMDIR (parseDir = false)
36 * @param parseDir boolean
37 * - true if user passed an entry point
38 * and wants to explore recursively the directories
39 * - false if user passed an already built DICOMDIR file
41 * @param exception_on_error whether we want to throw an exception or not
43 gdcmDicomDir::gdcmDicomDir(const char *FileName, bool parseDir,
44 bool exception_on_error):
45 gdcmParser(FileName,exception_on_error,true) // true : enable SeQuences
47 // que l'on ai passe un root directory ou un DICOMDIR
48 // et quelle que soit la valeur de parseDir,
49 // on a lance gdcmParser
54 startMethodArgDelete= NULL;
55 progressMethodArgDelete=NULL;
56 endMethodArgDelete= NULL;
66 // gdcmParser already executed
67 // if user passed a root directory, sure we didn't get anything
69 if( GetListEntry().begin()==GetListEntry().end() )
71 // if parseDir == false, it should be tagged as an error
72 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : entry list empty");
74 if(strlen(FileName)==1 && FileName[0]=='.') { // user passed '.' as Name
75 // we get current directory name
76 char*dummy=(char*) malloc(1000);
78 _getcwd(dummy,(size_t)1000);
80 getcwd(dummy,(size_t)1000);
82 SetFileName(dummy); // will be converted into a string
83 free(dummy); // no longer needed
88 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory and create the DicomDir");
94 CheckBoundaries(); // to maintain consistency between
95 // home-made gdcmDicomDir
96 // and the ones comming from a DICOMDIR file
101 * \ingroup gdcmDicomDir
102 * \brief Constructor : creates an empty gdcmDicomDir
103 * @param exception_on_error whether we want to throw an exception or not
105 gdcmDicomDir::gdcmDicomDir(bool exception_on_error):
106 gdcmParser(exception_on_error)
109 progressMethod= NULL;
111 startMethodArgDelete= NULL;
112 progressMethodArgDelete=NULL;
113 endMethodArgDelete= NULL;
120 std::string pathBidon = ""; // Sorry, NULL not allowed ...
121 SetElement(pathBidon, GDCM_DICOMDIR_META, NULL); // Set the META elements
123 AddDicomDirMetaToEnd(listEntries.begin(),--listEntries.end());
128 * \ingroup gdcmDicomDir
129 * \brief Canonical destructor
131 gdcmDicomDir::~gdcmDicomDir()
133 SetStartMethod(NULL);
134 SetProgressMethod(NULL);
140 for(ListDicomDirPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
146 //-----------------------------------------------------------------------------
149 * \ingroup gdcmDicomDir
150 * \brief Canonical Printer
152 void gdcmDicomDir::Print(std::ostream &os)
156 metaElems->SetPrintLevel(printLevel);
157 metaElems->Print(os);
159 for(ListDicomDirPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
161 (*cc)->SetPrintLevel(printLevel);
166 //-----------------------------------------------------------------------------
169 * \ingroup gdcmDicomDir
170 * \brief This predicate, based on hopefully reasonable heuristics,
171 * decides whether or not the current header was properly parsed
172 * and contains the mandatory information for being considered as
173 * a well formed and usable DicomDir.
174 * @return true when gdcmParser is the one of a reasonable DicomDir,
177 bool gdcmDicomDir::IsReadable(void)
179 if(!gdcmParser::IsReadable())
183 if(patients.size()<=0)
190 * \ingroup gdcmDicomDir
191 * \brief fills the whole structure, starting from a root Directory
193 void gdcmDicomDir::ParseDirectory(void)
195 CreateDicomDirChainedList(GetFileName());
200 * \ingroup gdcmDicomDir
201 * \brief Set the start method to call when the parsing of the directory starts
202 * @param method Method to call
203 * @param arg Argument to pass to the method
204 * @param argDelete Argument
205 * \warning In python : the arg parameter isn't considered
207 void gdcmDicomDir::SetStartMethod(gdcmMethod *method,void *arg,gdcmMethod *argDelete)
209 if((startArg)&&(startMethodArgDelete))
210 startMethodArgDelete(startArg);
214 startMethodArgDelete=argDelete;
218 * \ingroup gdcmDicomDir
219 * \brief Set the method to delete the argument
220 * The argument is destroyed when the method is changed or when the
222 * @param method Method to call to delete the argument
224 void gdcmDicomDir::SetStartMethodArgDelete(gdcmMethod *method)
226 startMethodArgDelete=method;
230 * \ingroup gdcmDicomDir
231 * \brief Set the progress method to call when the parsing of the directory progress
232 * @param method Method to call
233 * @param arg Argument to pass to the method
234 * @param argDelete Argument
235 * \warning In python : the arg parameter isn't considered
237 void gdcmDicomDir::SetProgressMethod(gdcmMethod *method,void *arg,gdcmMethod *argDelete)
239 if((progressArg)&&(progressMethodArgDelete))
240 progressMethodArgDelete(progressArg);
242 progressMethod=method;
244 progressMethodArgDelete=argDelete;
248 * \ingroup gdcmDicomDir
249 * \brief Set the method to delete the argument
250 * The argument is destroyed when the method is changed or when the
252 * @param method Method to call to delete the argument
254 void gdcmDicomDir::SetProgressMethodArgDelete(gdcmMethod *method)
256 progressMethodArgDelete=method;
260 * \ingroup gdcmDicomDir
261 * \brief Set the end method to call when the parsing of the directory ends
262 * @param method Method to call
263 * @param arg Argument to pass to the method
264 * @param argDelete Argument
265 * \warning In python : the arg parameter isn't considered
267 void gdcmDicomDir::SetEndMethod(gdcmMethod *method, void *arg, gdcmMethod *argDelete)
269 if((endArg)&&(endMethodArgDelete))
270 endMethodArgDelete(endArg);
274 endMethodArgDelete=argDelete;
278 * \ingroup gdcmDicomDir
279 * \brief Set the method to delete the argument
280 * The argument is destroyed when the method is changed or when the class
282 * @param method Method to call to delete the argument
284 void gdcmDicomDir::SetEndMethodArgDelete(gdcmMethod *method)
286 endMethodArgDelete=method;
290 * \ingroup gdcmDicomDir
291 * \brief writes on disc a DICOMDIR
292 * \ warning does NOT add the missing elements in the header :
293 * it's up to the user doing it !
294 * \todo : to be re-written using the DICOMDIR tree-like structure
295 * *not* the chained list
296 * (does NOT exist if the DICOMDIR is user-forged !)
297 * @param fileName file to be written to
298 * @return false only when fail to open
301 bool gdcmDicomDir::Write(std::string fileName)
305 fp1=fopen(fileName.c_str(),"wb");
308 printf("Failed to open(write) File [%s] \n",fileName.c_str());
313 filePreamble=(char*)calloc(128,1);
314 fwrite(filePreamble,128,1,fp1);
315 fwrite("DICM",4,1,fp1);
317 UpdateDirectoryRecordSequenceLength();
318 WriteDicomDirEntries(fp1);
325 * \ingroup gdcmParser
326 * \brief writes on disc according to the DICOMDIR format
327 * using the tree-like structure
328 * @param _fp already open file pointer
331 void gdcmDicomDir::WriteDicomDirEntries(FILE *_fp)
333 // TODO (?) tester les echecs en ecriture
334 // (apres chaque fwrite, dans le WriteEntry)
336 gdcmDicomDirMeta *ptrMeta;
337 ListDicomDirPatient::iterator itPatient;
338 ListDicomDirStudy::iterator itStudy;
339 ListDicomDirSerie::iterator itSerie;
340 ListDicomDirImage::iterator itImage;
343 ptrMeta= GetDicomDirMeta();
344 for(i=ptrMeta->debut();i!=ptrMeta->fin();++i) {
345 WriteEntry(*i,_fp,DICOMDIR);
348 itPatient = GetDicomDirPatients().begin();
349 while ( itPatient != GetDicomDirPatients().end() ) {
350 for(i=(*itPatient)->debut();i!=(*itPatient)->fin();++i) {
351 WriteEntry(*i,_fp,DICOMDIR);
353 itStudy = ((*itPatient)->GetDicomDirStudies()).begin();
354 while (itStudy != (*itPatient)->GetDicomDirStudies().end() ) {
355 for(i=(*itStudy)->debut();i!=(*itStudy)->fin();++i) {
356 WriteEntry(*i,_fp,DICOMDIR);
358 itSerie = ((*itStudy)->GetDicomDirSeries()).begin();
359 while (itSerie != (*itStudy)->GetDicomDirSeries().end() ) {
360 for(i=(*itSerie)->debut();i!=(*itSerie)->fin();++i) {
361 WriteEntry(*i,_fp,DICOMDIR);
363 itImage = ((*itSerie)->GetDicomDirImages()).begin();
364 while (itImage != (*itSerie)->GetDicomDirImages().end() ) {
365 for(i=(*itImage)->debut();i!=(*itImage)->fin();++i) {
366 WriteEntry(*i,_fp,DICOMDIR);
378 //-----------------------------------------------------------------------------
382 * \ingroup gdcmDicomDir
383 * \brief create a gdcmHeader-like chained list from a root Directory
384 * @param path entry point of the tree-like structure
386 void gdcmDicomDir::CreateDicomDirChainedList(std::string path)
390 gdcmDirList fileList(path,1); // gets recursively the file list
391 unsigned int count=0;
398 for(gdcmDirList::iterator it=fileList.begin();
402 progress=(float)(count+1)/(float)fileList.size();
403 CallProgressMethod();
407 header=new gdcmHeader(it->c_str());
408 if(header->IsReadable())
409 list.push_back(header); // adds the file header to the chained list
415 // sorts Patient/Study/Serie/
416 std::sort(list.begin(),list.end(),gdcmDicomDir::HeaderLessThan);
418 std::string tmp=fileList.GetDirName();
420 //for each Header of the chained list, add/update the Patient/Study/Serie/Image info
421 SetElements(tmp,list);
427 * \ingroup gdcmDicomDir
428 * \brief modifies the limits of a gdcmObject, created from a DICOMDIR file
431 void gdcmDicomDir::CheckBoundaries()
433 ListDicomDirPatient::iterator itPatient;
434 ListDicomDirStudy::iterator itStudy;
435 ListDicomDirSerie::iterator itSerie;
436 ListDicomDirImage::iterator itImage;
437 ListTag::iterator i,j;
439 GetDicomDirMeta()->ResetBoundaries(0);
441 itPatient = GetDicomDirPatients().begin();
442 while ( itPatient != GetDicomDirPatients().end() ) {
443 (*itPatient)->ResetBoundaries(1);
444 itStudy = ((*itPatient)->GetDicomDirStudies()).begin();
445 while (itStudy != (*itPatient)->GetDicomDirStudies().end() ) {
446 (*itStudy)->ResetBoundaries(1);
447 itSerie = ((*itStudy)->GetDicomDirSeries()).begin();
448 while (itSerie != (*itStudy)->GetDicomDirSeries().end() ) {
449 (*itSerie)->ResetBoundaries(1);
450 itImage = ((*itSerie)->GetDicomDirImages()).begin();
451 while (itImage != (*itSerie)->GetDicomDirImages().end() ) {
452 (*itImage)->ResetBoundaries(1);
465 * \ingroup gdcmDicomDir
466 * \brief adds a new Patient to a partially created DICOMDIR
468 gdcmDicomDirPatient * gdcmDicomDir::NewPatient(void) {
469 std::list<gdcmElement> elemList;
470 std::list<gdcmElement>::iterator it;
472 gdcmDictEntry *dictEntry;
473 gdcmHeaderEntry *entry;
475 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirPatientElements();
476 std::list<gdcmHeaderEntry *>::iterator debInsertion, finInsertion, i,j;
478 debInsertion = metaElems->fin();
480 finInsertion=debInsertion;
482 // for all the DicomDirPatient Elements
483 for(it=elemList.begin();it!=elemList.end();++it)
487 dictEntry=GetPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
488 entry=new gdcmHeaderEntry(dictEntry);
489 entry->SetOffset(0); // just to avoid missprinting
490 entry->SetValue(it->value);
492 if(dictEntry->GetGroup()==0xfffe)
494 entry->SetLength(entry->GetValue().length());
496 else if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") )
500 else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") )
504 else if(dictEntry->GetVR()=="SQ")
506 entry->SetLength(0xffffffff);
510 entry->SetLength(entry->GetValue().length());
513 tagHT.insert( PairHT(entry->GetKey(),entry) ); // add in the (multimap) H Table
514 listEntries.insert(debInsertion ,entry); // en tete de liste des Patients
521 gdcmDicomDirPatient *p = new gdcmDicomDirPatient(i, --debInsertion,
522 &tagHT, &listEntries);
523 patients.push_front(p);
528 * \ingroup gdcmDicomDir
529 * \brief CallStartMethod
531 void gdcmDicomDir::CallStartMethod(void)
536 startMethod(startArg);
539 * \ingroup gdcmDicomDir
540 * \brief CallProgressMethod
542 void gdcmDicomDir::CallProgressMethod(void)
545 progressMethod(progressArg);
548 * \ingroup gdcmDicomDir
549 * \brief CallEndMethod
551 void gdcmDicomDir::CallEndMethod(void)
558 //-----------------------------------------------------------------------------
561 * \ingroup gdcmDicomDir
562 * \brief create a 'gdcmDicomDir' from a DICOMDIR gdcmHeader
564 void gdcmDicomDir::CreateDicomDir()
566 // The list is parsed.
567 // When a DicomDir tag ("PATIENT", "STUDY", "SERIE", "IMAGE") is found :
568 // 1 - we save the beginning iterator
569 // 2 - we continue to parse
570 // 3 - we find an other tag
571 // + we create the object for the precedent tag
574 gdcmDicomDirType type=gdcmDicomDir::GDCM_DICOMDIR_META;
575 ListTag::iterator begin;
576 ListTag::iterator end, end2;
578 begin=listEntries.begin();
580 for(ListTag::iterator i=end;i !=listEntries.end();++i)
582 std::string v=(*i)->GetValue();
586 AddObjectToEnd(type,begin,--end2);
587 type=gdcmDicomDir::GDCM_DICOMDIR_PATIENT;
594 AddObjectToEnd(type,begin,--end2);
595 type=gdcmDicomDir::GDCM_DICOMDIR_STUDY;
602 AddObjectToEnd(type,begin,--end2);
603 type=gdcmDicomDir::GDCM_DICOMDIR_SERIE;
610 AddObjectToEnd(type,begin,--end2);
611 type=gdcmDicomDir::GDCM_DICOMDIR_IMAGE;
616 end=end2=listEntries.end();
618 AddObjectToEnd(type,begin,--end2);
621 * \ingroup gdcmDicomDir
622 * \brief AddObjectToEnd
624 * @param begin iterator on the first HeaderEntry within the chained List
625 * @param end iterator on the last HeaderEntry within the chained List
627 void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,ListTag::iterator begin,ListTag::iterator end)
634 case gdcmDicomDir::GDCM_DICOMDIR_META:
635 AddDicomDirMetaToEnd(begin,end);
637 case gdcmDicomDir::GDCM_DICOMDIR_PATIENT:
638 AddDicomDirPatientToEnd(begin,end);
640 case gdcmDicomDir::GDCM_DICOMDIR_STUDY:
641 AddDicomDirStudyToEnd(begin,end);
643 case gdcmDicomDir::GDCM_DICOMDIR_SERIE:
644 AddDicomDirSerieToEnd(begin,end);
646 case gdcmDicomDir::GDCM_DICOMDIR_IMAGE:
647 AddDicomDirImageToEnd(begin,end);
653 * \ingroup gdcmDicomDir
654 * \brief Well ... Not realy to end, there is only one occurence
655 * @param begin iterator on the first HeaderEntry within the chained List
656 * @param end iterator on the last HeaderEntry within the chained List
658 void gdcmDicomDir::AddDicomDirMetaToEnd(ListTag::iterator begin,ListTag::iterator end)
662 metaElems = new gdcmDicomDirMeta(begin,end,&tagHT,&listEntries);
666 * \ingroup gdcmDicomDir
667 * \brief AddDicomDirPatientToEnd
668 * @param begin iterator on the first HeaderEntry within the chained List
669 * @param end iterator on the last HeaderEntry within the chained List
671 void gdcmDicomDir::AddDicomDirPatientToEnd(ListTag::iterator begin,ListTag::iterator end)
673 patients.push_back(new gdcmDicomDirPatient(begin,end,&tagHT, &listEntries));
677 * \ingroup gdcmDicomDir
678 * \brief AddDicomDirStudyToEnd
679 * @param begin iterator on the first HeaderEntry within the chained List
680 * @param end iterator on the last HeaderEntry within the chained List
682 void gdcmDicomDir::AddDicomDirStudyToEnd(ListTag::iterator begin,ListTag::iterator end)
684 if(patients.size()>0)
686 ListDicomDirPatient::iterator itp=patients.end();
688 (*itp)->AddDicomDirStudy(new gdcmDicomDirStudy(begin,end,&tagHT, &listEntries));
692 * \ingroup gdcmDicomDir
693 * \brief AddDicomDirSerieToEnd
694 * @param begin iterator on the first HeaderEntry within the chained List
695 * @param end iterator on the last HeaderEntry within the chained List
697 void gdcmDicomDir::AddDicomDirSerieToEnd(ListTag::iterator begin,ListTag::iterator end)
699 if(patients.size()>0)
701 ListDicomDirPatient::iterator itp=patients.end();
704 if((*itp)->GetDicomDirStudies().size()>0)
706 ListDicomDirStudy::iterator itst=(*itp)->GetDicomDirStudies().end();
708 (*itst)->AddDicomDirSerie(new gdcmDicomDirSerie(begin,end,&tagHT, &listEntries));
714 * \ingroup gdcmDicomDir
715 * \brief AddDicomDirImageToEnd
716 * @param begin iterator on the first HeaderEntry within the chained List
717 * @param end iterator on the last HeaderEntry within the chained List
719 void gdcmDicomDir::AddDicomDirImageToEnd(ListTag::iterator begin,ListTag::iterator end)
721 if(patients.size()>0)
723 ListDicomDirPatient::iterator itp=patients.end();
726 if((*itp)->GetDicomDirStudies().size()>0)
728 ListDicomDirStudy::iterator itst=(*itp)->GetDicomDirStudies().end();
731 if((*itst)->GetDicomDirSeries().size()>0)
733 ListDicomDirSerie::iterator its=(*itst)->GetDicomDirSeries().end();
735 (*its)->AddDicomDirImage(new gdcmDicomDirImage(begin,end,&tagHT, &listEntries));
742 * \ingroup gdcmDicomDir
743 * \brief for each Header of the chained list, add/update the Patient/Study/Serie/Image info
744 * @param path path of the root directory
745 * @param list chained list of Headers
747 void gdcmDicomDir::SetElements(std::string &path, ListHeader &list)
749 std::string patPrevName="", patPrevID="";
750 std::string studPrevInstanceUID="", studPrevID="";
751 std::string serPrevInstanceUID="", serPrevID="";
753 std::string patCurName, patCurID;
754 std::string studCurInstanceUID, studCurID;
755 std::string serCurInstanceUID, serCurID;
757 SetElement(path,GDCM_DICOMDIR_META,NULL);
759 ListTag::iterator debPat=listEntries.begin();
760 for(ListHeader::iterator it=list.begin();it!=list.end();++it)
762 // get the current file characteristics
763 patCurName= (*it)->GetEntryByNumber(0x0010,0x0010);
764 patCurID= (*it)->GetEntryByNumber(0x0010,0x0011);
765 studCurInstanceUID=(*it)->GetEntryByNumber(0x0020,0x000d);
766 studCurID= (*it)->GetEntryByNumber(0x0020,0x0010);
767 serCurInstanceUID= (*it)->GetEntryByNumber(0x0020,0x000e);
768 serCurID= (*it)->GetEntryByNumber(0x0020,0x0011);
770 if(patCurName!=patPrevName || patCurID!=patPrevID)
771 SetElement(path,GDCM_DICOMDIR_PATIENT,*it);
773 // if new Study Deal with 'STUDY' Elements
774 if(studCurInstanceUID!=studPrevInstanceUID || studCurID!=studPrevID)
775 SetElement(path,GDCM_DICOMDIR_STUDY,*it);
777 // if new Serie Deal with 'SERIE' Elements
778 if(serCurInstanceUID!=serPrevInstanceUID || serCurID!=serPrevID)
779 SetElement(path,GDCM_DICOMDIR_SERIE,*it);
781 // Always Deal with 'IMAGE' Elements
782 SetElement(path,GDCM_DICOMDIR_IMAGE,*it);
784 patPrevName= patCurName;
786 studPrevInstanceUID=studCurInstanceUID;
787 studPrevID= studCurID;
788 serPrevInstanceUID= serCurInstanceUID;
794 * \ingroup gdcmDicomDir
795 * \brief adds to the HTable and at the end of the Chained List
796 * the gdcmEntries (Dicom Elements) corresponding to the given type
797 * @param path full path file name(only used when type = GDCM_DICOMDIR_IMAGE
798 * @param type gdcmObject type to create (GDCM_DICOMDIR_PATIENT, GDCM_DICOMDIR_STUDY, GDCM_DICOMDIR_SERIE ...)
799 * @param header gdcmHeader of the current file
801 void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader *header)
803 std::list<gdcmElement> elemList;
804 std::list<gdcmElement>::iterator it;
805 guint16 tmpGr, tmpEl;
806 gdcmDictEntry *dictEntry;
807 gdcmHeaderEntry *entry;
812 case GDCM_DICOMDIR_PATIENT:
813 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirPatientElements();
815 case GDCM_DICOMDIR_STUDY:
816 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirStudyElements();
818 case GDCM_DICOMDIR_SERIE:
819 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirSerieElements();
821 case GDCM_DICOMDIR_IMAGE:
822 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirImageElements();
824 case GDCM_DICOMDIR_META:
825 elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirMetaElements();
831 for(it=elemList.begin();it!=elemList.end();++it)
835 dictEntry=GetPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
836 entry=new gdcmHeaderEntry(dictEntry);
837 entry->SetOffset(0); // just to avoid missprinting
840 val=header->GetEntryByNumber(tmpGr,tmpEl);
844 if(val==GDCM_UNFOUND)
846 if((tmpGr==0x0004) &&(tmpEl==0x1130) ) // File-set ID
848 // force to the *end* File Name
851 else if( (tmpGr==0x0004) && (tmpEl==0x1500) ) // Only used for image
853 if(header->GetFileName().substr(0,path.length())!=path)
855 dbg.Verbose(0, "gdcmDicomDir::SetElement : the base path of file name is incorrect");
856 val=header->GetFileName();
859 val=&(header->GetFileName().c_str()[path.length()]);
869 if (header->GetEntryLengthByNumber(tmpGr,tmpEl)== 0)
873 entry->SetValue(val);
877 if(dictEntry->GetGroup()==0xfffe)
879 entry->SetLength(entry->GetValue().length());
881 else if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") )
885 else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") )
889 else if(dictEntry->GetVR()=="SQ")
891 entry->SetLength(0xffffffff);
895 entry->SetLength(entry->GetValue().length());
898 //AddHeaderEntry(entry); // both in H Table and in chained list
899 tagHT.insert( PairHT( entry->GetKey(),entry) );
900 listEntries.push_back(entry);
901 //wasUpdated = 1; // is private
905 * \ingroup gdcmDicomDir
906 * \brief compares two dgcmHeaders
908 bool gdcmDicomDir::HeaderLessThan(gdcmHeader *header1,gdcmHeader *header2)
910 return(*header1<*header2);
914 * \ingroup gdcmDicomDir
915 * \brief Sets the accurate value for the (0x0004,0x1220) element of a DICOMDIR
918 void gdcmDicomDir::UpdateDirectoryRecordSequenceLength() {
920 ListTag::iterator it;
923 for(it=listEntries.begin();it!=listEntries.end();++it) {
924 gr = (*it)->GetGroup();
925 el = (*it)->GetElement();
928 if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ) {
929 offset += 4; // explicit VR AND OB, OW, SQ : 4 more bytes
931 offset += 2 + 2 + 4 + (*it)->GetLength();
933 offset += 4; // delimiters don't have a value.
936 bool res=SetEntryLengthByNumber(offset, 0x0004, 0x1220); // Hope there is no dupps.
940 //-----------------------------------------------------------------------------