X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmDicomDir.cxx;h=92cdc6f8702234cf7474e1132bf527ec82ede3d0;hb=a23d3b0e36743664f22f42269224f305ccf50fdb;hp=078c357514d0e5157380b64ca239907483b94db8;hpb=45bf98d79625d7efdb227b07c8746a918b49568b;p=gdcm.git diff --git a/src/gdcmDicomDir.cxx b/src/gdcmDicomDir.cxx index 078c3575..92cdc6f8 100644 --- a/src/gdcmDicomDir.cxx +++ b/src/gdcmDicomDir.cxx @@ -4,43 +4,53 @@ #include "gdcmStudy.h" #include "gdcmSerie.h" #include "gdcmImage.h" +#include "gdcmDirList.h" #include "gdcmUtil.h" #include +#include + +#include +#include //----------------------------------------------------------------------------- // Constructor / Destructor - /* * \ingroup gdcmDicomDir * \brief * @param Filename * @param exception_on_error */ -gdcmDicomDir::gdcmDicomDir(std::string & FileName, +gdcmDicomDir::gdcmDicomDir(const char *FileName, bool parseDir, bool exception_on_error): - gdcmParser(FileName.c_str(),exception_on_error, true ) + gdcmParser(FileName,exception_on_error,true) { - if ( GetListEntry().begin() == GetListEntry().end() ) + if( GetListEntry().begin()==GetListEntry().end() ) { - dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir entry list empty"); - } - CreateDicomDir(); -} + dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : entry list empty"); + if(parseDir) + { + dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory and create the DicomDir"); + ParseDirectory(); + } + } + else + CreateDicomDir(); +} /* * \ingroup gdcmDicomDir * \brief * @param exception_on_error */ -gdcmDicomDir::gdcmDicomDir(ListTag *l, +/*gdcmDicomDir::gdcmDicomDir(ListTag *l, bool exception_on_error): gdcmParser(exception_on_error ) { listEntries=*l; CreateDicomDir(); -} +}*/ /* * \ingroup gdcmDicomDir @@ -48,29 +58,25 @@ gdcmDicomDir::gdcmDicomDir(ListTag *l, */ gdcmDicomDir::~gdcmDicomDir() { - for(ListPatient::iterator cc = patients.begin();cc!=patients.end();++cc) + for(ListPatient::iterator cc=patients.begin();cc!=patients.end();++cc) { delete *cc; } } - - //----------------------------------------------------------------------------- // Print void gdcmDicomDir::Print(std::ostream &os) { - for(ListPatient::iterator cc = patients.begin();cc!=patients.end();++cc) + for(ListPatient::iterator cc=patients.begin();cc!=patients.end();++cc) { - (*cc)->SetPrintLevel(printLevel); - (*cc)->Print(os); + (*cc)->SetPrintLevel(printLevel); + (*cc)->Print(os); } } //----------------------------------------------------------------------------- // Public - - /** * \ingroup gdcmDicomDir * \brief writes on disc a DICOMDIR @@ -79,27 +85,85 @@ void gdcmDicomDir::Print(std::ostream &os) * @param fileName file to be written to * @return */ -bool gdcmDicomDir::Write(std::string fileName) { - +bool gdcmDicomDir::Write(std::string fileName) +{ FILE * fp1; - fp1 = fopen(fileName.c_str(),"wb"); - if (fp1 == NULL) { - printf("Failed to open (write) File [%s] \n",fileName.c_str()); - return (false); + + fp1=fopen(fileName.c_str(),"wb"); + if(fp1==NULL) + { + printf("Failed to open(write) File [%s] \n",fileName.c_str()); + return(false); } - char * filePreamble; + + char * filePreamble; filePreamble=(char*)calloc(128,1); fwrite(filePreamble,128,1,fp1); fwrite("DICM",4,1,fp1); - free (filePreamble); - WriteEntries(DICOMDIR,fp1); - + free(filePreamble); + + WriteEntries(fp1,DICOMDIR); + + fclose(fp1); + return true; +} +void gdcmDicomDir::ParseDirectory(void) +{ + NewDicomDir(GetPath()); + CreateDicomDir(); } //----------------------------------------------------------------------------- // Protected +/* + * \ingroup gdcmDicomDir + * \brief + * @param + */ +void gdcmDicomDir::NewDicomDir(std::string path) +{ + gdcmDirList fileList(path,1); + ListHeader list; + gdcmHeader *header; + + listEntries.clear(); + patients.clear(); + + for(gdcmDirList::iterator it=fileList.begin(); + it!=fileList.end(); ++it) + { + header=new gdcmHeader(it->c_str()); + if(header->IsReadable()) + list.push_back(header); + else + delete header; + } + + std::sort(list.begin(),list.end(),gdcmDicomDir::HeaderLessThan); + + SetElements(path,list); +} + +/* + * \ingroup gdcmDicomDir + * \brief Get the dicom dir path + * @param + */ +std::string gdcmDicomDir::GetPath(void) +{ + std::string path=GetFileName(); + + int pos1=path.rfind("/"); + int pos2=path.rfind("\\"); + if(pos1>pos2) + path.resize(pos1); + else + path.resize(pos2); + + return(path); +} //----------------------------------------------------------------------------- // Private @@ -123,15 +187,11 @@ void gdcmDicomDir::CreateDicomDir() begin=listEntries.begin(); end=begin; - for(ListTag::iterator i=listEntries.begin();i != listEntries.end();++i) + for(ListTag::iterator i=listEntries.begin();i !=listEntries.end();++i) { - // std::cout << std::hex << (*i)->GetGroup() << - // " " << (*i)->GetElement() << endl; - - std::string v = (*i)->GetValue(); - if (v == "PATIENT ") + std::string v=(*i)->GetValue(); + if(v=="PATIENT ") { - // std::cout<<"PATIENT"<AddStudy(new gdcmStudy(begin,end)); + (*itp)->AddStudy(new gdcmStudy(begin,end)); } } /* @@ -240,7 +297,7 @@ void gdcmDicomDir::AddSerieToEnd(ListTag::iterator begin,ListTag::iterator end) { ListStudy::iterator itst=(*itp)->GetStudies().end(); itst--; - (*itst)->AddSerie(new gdcmSerie(begin,end)); + (*itst)->AddSerie(new gdcmSerie(begin,end)); } } } @@ -266,10 +323,165 @@ void gdcmDicomDir::AddSerieToEnd(ListTag::iterator begin,ListTag::iterator end) { ListSerie::iterator its=(*itst)->GetSeries().end(); its--; - (*its)->AddImage(new gdcmImage(begin,end)); + (*its)->AddImage(new gdcmImage(begin,end)); } } } } +/* + * \ingroup gdcmDicomDir + * \brief + * @param + */ +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_NONE,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_PATIENT,*it); + + // if new Study Deal with 'STUDY' Elements + if(studCurInstanceUID!=studPrevInstanceUID || studCurID!=studPrevID) + SetElement(path,GDCM_STUDY,*it); + + // if new Serie Deal with 'SERIE' Elements + if(serCurInstanceUID!=serPrevInstanceUID || serCurID!=serPrevID) + { + SetElement(path,GDCM_SERIE,*it); + } + + // Always Deal with 'IMAGE' Elements + SetElement(path,GDCM_IMAGE,*it); + + patPrevName=patCurName; + patPrevID=patCurID; + studPrevInstanceUID=studCurInstanceUID; + studPrevID=studCurID; + serPrevInstanceUID=serCurInstanceUID; + serPrevID=serCurID; + } +} + +/* + * \ingroup gdcmDicomDir + * \brief + * @param + */ +void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader *header) +{ + std::list elemList; + std::list::iterator it; + guint16 tmpGr, tmpEl; + gdcmDictEntry *dictEntry; + gdcmHeaderEntry *entry; + std::string val; + + switch(type) + { + case GDCM_PATIENT: + elemList=gdcmGlobal::GetDicomDirElements()->GetPatientElements(); + break; + case GDCM_STUDY: + elemList=gdcmGlobal::GetDicomDirElements()->GetStudyElements(); + break; + case GDCM_SERIE: + elemList=gdcmGlobal::GetDicomDirElements()->GetSerieElements(); + break; + case GDCM_IMAGE: + elemList=gdcmGlobal::GetDicomDirElements()->GetImageElements(); + break; + case GDCM_NONE: + elemList=gdcmGlobal::GetDicomDirElements()->GetMetaElements(); + 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) ) + { + // TODO force the *end* File Name(remove path) + val=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()[path.length()]); + } + else + { + val=it->value; + } + } + entry->SetValue(val); + + if(dictEntry) + { + 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()); + } + } + + listEntries.push_back(entry); + } +} + +bool gdcmDicomDir::HeaderLessThan(gdcmHeader *header1,gdcmHeader *header2) +{ + return(*header1<*header2); +} + //-----------------------------------------------------------------------------