+/**
+ * \ingroup gdcmDicomDir
+ * \brief for each Header of the chained list, add/update the Patient/Study/Serie/Image info
+ * @param path path of the root directory
+ * @param list chained list of Headers
+ */
+void gdcmDicomDir::SetElements(std::string &path, ListHeader &list)
+{
+ std::string patPrevName="", patPrevID="";
+ std::string studPrevInstanceUID="", studPrevID="";
+ std::string serPrevInstanceUID="", serPrevID="";
+
+ std::string patCurName, patCurID;
+ std::string studCurInstanceUID, studCurID;
+ std::string serCurInstanceUID, serCurID;
+
+ SetElement(path,GDCM_DICOMDIR_META,NULL);
+
+ ListTag::iterator debPat=listEntries.begin();
+ for(ListHeader::iterator it=list.begin();it!=list.end();++it)
+ {
+ // get the current file characteristics
+ patCurName= (*it)->GetEntryByNumber(0x0010,0x0010);
+ patCurID= (*it)->GetEntryByNumber(0x0010,0x0011);
+ studCurInstanceUID=(*it)->GetEntryByNumber(0x0020,0x000d);
+ studCurID= (*it)->GetEntryByNumber(0x0020,0x0010);
+ serCurInstanceUID= (*it)->GetEntryByNumber(0x0020,0x000e);
+ serCurID= (*it)->GetEntryByNumber(0x0020,0x0011);
+
+ if(patCurName!=patPrevName || patCurID!=patPrevID)
+ SetElement(path,GDCM_DICOMDIR_PATIENT,*it);
+
+ // if new Study Deal with 'STUDY' Elements
+ if(studCurInstanceUID!=studPrevInstanceUID || studCurID!=studPrevID)
+ SetElement(path,GDCM_DICOMDIR_STUDY,*it);
+
+ // if new Serie Deal with 'SERIE' Elements
+ if(serCurInstanceUID!=serPrevInstanceUID || serCurID!=serPrevID)
+ SetElement(path,GDCM_DICOMDIR_SERIE,*it);
+
+ // Always Deal with 'IMAGE' Elements
+ SetElement(path,GDCM_DICOMDIR_IMAGE,*it);
+
+ patPrevName= patCurName;
+ patPrevID= patCurID;
+ studPrevInstanceUID=studCurInstanceUID;
+ studPrevID= studCurID;
+ serPrevInstanceUID= serCurInstanceUID;
+ serPrevID= serCurID;
+ }
+}
+
+/**
+ * \ingroup gdcmDicomDir
+ * \brief adds to the HTable and at the end of the Chained List
+ * the gdcmEntries (Dicom Elements) corresponding to the given type
+ * @param path full path file name(only used when type = GDCM_DICOMDIR_IMAGE
+ * @param type gdcmObject type to create (GDCM_DICOMDIR_PATIENT, GDCM_DICOMDIR_STUDY, GDCM_DICOMDIR_SERIE ...)
+ * @param header gdcmHeader of the current file
+ */
+void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader *header)
+{
+ std::list<gdcmElement> elemList;
+ std::list<gdcmElement>::iterator it;
+ guint16 tmpGr, tmpEl;
+ gdcmDictEntry *dictEntry;
+ gdcmHeaderEntry *entry;
+ std::string val;
+
+ switch(type)
+ {
+ case GDCM_DICOMDIR_PATIENT:
+ elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirPatientElements();
+ break;
+ case GDCM_DICOMDIR_STUDY:
+ elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirStudyElements();
+ break;
+ case GDCM_DICOMDIR_SERIE:
+ elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirSerieElements();
+ break;
+ case GDCM_DICOMDIR_IMAGE:
+ elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirImageElements();
+ break;
+ case GDCM_DICOMDIR_META:
+ elemList=gdcmGlobal::GetDicomDirElements()->GetDicomDirMetaElements();
+ break;
+ default:
+ return;
+ }
+
+ for(it=elemList.begin();it!=elemList.end();++it)
+ {
+ tmpGr=it->group;
+ tmpEl=it->elem;
+ dictEntry=GetPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
+ entry=new gdcmHeaderEntry(dictEntry);
+ entry->SetOffset(0); // just to avoid missprinting
+
+ if(header)
+ val=header->GetEntryByNumber(tmpGr,tmpEl);
+ else
+ val=GDCM_UNFOUND;
+
+ if(val==GDCM_UNFOUND)
+ {
+ if((tmpGr==0x0004) &&(tmpEl==0x1130) ) // File-set ID
+ {
+ // force to the *end* File Name
+ val=GetName(path);
+ }
+ else if( (tmpGr==0x0004) && (tmpEl==0x1500) ) // Only used for image
+ {
+ if(header->GetFileName().substr(0,path.length())!=path)
+ {
+ dbg.Verbose(0, "gdcmDicomDir::SetElement : the base path of file name is incorrect");
+ val=header->GetFileName();
+ }
+ else {
+ val=&(header->GetFileName().c_str()[path.length()]);
+ }
+ }
+ else
+ {
+ val=it->value;
+ }
+ }
+ else
+ {
+ if (header->GetEntryLengthByNumber(tmpGr,tmpEl)== 0)
+ val=it->value;
+ }
+
+ entry->SetValue(val);
+
+ if(dictEntry)
+ {
+ if(dictEntry->GetGroup()==0xfffe)
+ {
+ entry->SetLength(entry->GetValue().length());
+ }
+ else if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") )
+ {
+ entry->SetLength(4);
+ }
+ else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") )
+ {
+ entry->SetLength(2);
+ }
+ else if(dictEntry->GetVR()=="SQ")
+ {
+ entry->SetLength(0xffffffff);
+ }
+ else
+ {
+ entry->SetLength(entry->GetValue().length());
+ }
+ }
+ //AddHeaderEntry(entry); // both in H Table and in chained list
+ tagHT.insert( PairHT( entry->GetKey(),entry) );
+ listEntries.push_back(entry);
+ //wasUpdated = 1; // is private
+ }
+}
+/**
+ * \ingroup gdcmDicomDir
+ * \brief compares two dgcmHeaders
+ */
+bool gdcmDicomDir::HeaderLessThan(gdcmHeader *header1,gdcmHeader *header2)
+{
+ return(*header1<*header2);
+}
+
+/**
+ * \ingroup gdcmDicomDir
+ * \brief Sets the accurate value for the (0x0004,0x1220) element of a DICOMDIR
+ */
+
+void gdcmDicomDir::UpdateDirectoryRecordSequenceLength() {
+ int offset = 0;
+ ListTag::iterator it;
+ guint16 gr, el;
+ std::string vr;
+ for(it=listEntries.begin();it!=listEntries.end();++it) {
+ gr = (*it)->GetGroup();
+ el = (*it)->GetElement();
+ vr = (*it)->GetVR();
+ if (gr !=0xfffe) {
+ if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ) {
+ offset += 4; // explicit VR AND OB, OW, SQ : 4 more bytes
+ }
+ offset += 2 + 2 + 4 + (*it)->GetLength();
+ } else {
+ offset += 4; // delimiters don't have a value.
+ }
+ }
+ //bool res=SetEntryLengthByNumber(offset, 0x0004, 0x1220); // Hope there is no dupps.
+ SetEntryLengthByNumber(offset, 0x0004, 0x1220); // Hope there is no dupps.
+ return;
+}
+