From: regrain Date: Tue, 3 Feb 2004 18:08:32 +0000 (+0000) Subject: * gdcmDirList : to parse a hard drive directory in recursive (or not) X-Git-Tag: Version0.4~36 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=4d59e5e9778e5abff13d13d576ef92ce81498b6f;p=gdcm.git * gdcmDirList : to parse a hard drive directory in recursive (or not) * gdcmDicomDir : add the load of directory * Bug fix and print add-on -- BeNours --- diff --git a/ChangeLog b/ChangeLog index e92b3afc..009f3f36 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,16 +1,22 @@ +2004-02-03 Benoit Regrain + * gdcmDirList : to parse a hard drive directory in recursive (or not) + * gdcmDicomDir : add the load of directory + * Bug fix and print add-on + 2004-02-03 Jean-Pierre Roux * ENH gdcmParser : allows "DICM" files, with NO group '0002' 2004-02-02 Jean-Pierre Roux - * FIX : gdcmWrite : equal_range() for multimap doesn't return a 'second' iterator on last + * FIX : gdcmWrite : equal_range() for multimap doesn't return a 'second' + iterator on last of the last synonym :-( - * FIX : gdcmWrite::WriteBase : method stops if Pixels not yet Read (except for - DICOMDIR ;-) - * ENH gdcmData/checkWrite.sh :modif for full check of Explicit VR writting + * FIX : gdcmWrite::WriteBase : method stops if Pixels not yet Read (except + for DICOMDIR ;-) + * ENH gdcmData/checkWrite.sh :modif for full check of Explicit VR writting * FIX taking into account the possible 7fe0,0010 multiplicity * FIX add GRPixel,NumPixel,countGrPixel (gdcmParser protected members) to allow removal of references to 7fe0,0010, to deal with - ACR-NEMA images, when 0028,0200 is meaningfull + ACR-NEMA images, when 0028,0200 is meaningfull 2004-01-31 Jean-Pierre Roux * FIX gdcmParser::WriteEntries : when a VR is tagged as 'Unknown' diff --git a/Testing/TestDicomDir.cxx b/Testing/TestDicomDir.cxx index 5462c9ff..4da27044 100644 --- a/Testing/TestDicomDir.cxx +++ b/Testing/TestDicomDir.cxx @@ -51,7 +51,7 @@ int main(int argc, char* argv[]) else file = "../gdcmData/DICOMDIR"; - e1 = new gdcmDicomDir(file); + e1 = new gdcmDicomDir(file.c_str()); if (argc > 2) { int level = atoi(argv[2]); e1->SetPrintLevel(level); diff --git a/gdcm.dsw b/gdcm.dsw index da6ae498..838a0c0c 100644 --- a/gdcm.dsw +++ b/gdcm.dsw @@ -62,6 +62,9 @@ Package=<5> Package=<4> {{{ + Begin Project Dependency + Project_Dep_Name gdcmdll + End Project Dependency }}} ############################################################################### diff --git a/src/gdcmDicomDir.cxx b/src/gdcmDicomDir.cxx index 078c3575..111f0e0f 100644 --- a/src/gdcmDicomDir.cxx +++ b/src/gdcmDicomDir.cxx @@ -4,31 +4,228 @@ #include "gdcmStudy.h" #include "gdcmSerie.h" #include "gdcmImage.h" +#include "gdcmDirList.h" #include "gdcmUtil.h" #include +#include +#include + //----------------------------------------------------------------------------- -// Constructor / Destructor +class ELEMENTS +{ +public : + ELEMENTS(unsigned short int _group,unsigned short int _elem,std::string _value) + {group=_group;elem=_elem;value=_value;} + + unsigned short int group; + unsigned short int elem; + std::string value; +}; + +ELEMENTS metaElem[]={ + //Meta Group Length : to be computed later + ELEMENTS(0x0002,0x0000,"12345"), + //File Meta Information Version + ELEMENTS(0x0002,0x0001,"\2\0\0\0"), + //Media Stored SOP Class UID i.e. : 'Media Storage Directory Storage' + ELEMENTS(0x0002,0x0002,"1.2.840.10008.1.3.10"), + //Media Stored SOP Instance UID : may be forged later + ELEMENTS(0x0002,0x0003,""), + //Transfer Syntax UID i.e. : Explicit VR - Little Endian + ELEMENTS(0x0002,0x0010,"1.2.840.10008.1.2.1"), + //Implementation Class UID : may be forged later + ELEMENTS(0x0002,0x0012,""), + //Implementation Version Name + ELEMENTS(0x0002,0x0013,"gdcmLib"), + //File-set ID : + ELEMENTS(0x0004,0x1130,""), + //Offset of the first dir of root dir entity : to be computed later + ELEMENTS(0x0004,0x1200,"0"), + //Offset of the last dir of root dir entity : to be computed later + ELEMENTS(0x0004,0x1202,"0"), + //File-set consistency flag + ELEMENTS(0x0004,0x1212,"0"), + //Directory record sequence : *length* to be set later + ELEMENTS(0x0004,0x1220,"0"), + ELEMENTS(0xffff,0xffff,"") +} ; + +ELEMENTS patientElem[]={ + ELEMENTS(0xfffe,0xe000,"0"), + // Offset of next directory record : to be computed later + ELEMENTS(0x0004,0x1400,"0"), + // Record in use flag : 65535(?) + ELEMENTS(0x0004,0x1410,"65535"), + // Offset of referenced lower-level dir entity : to be computed later + ELEMENTS(0x0004,0x1420,"0"), + // Directory Record Type + ELEMENTS(0x0004,0x1430,"PATIENT "), // don't remove trailing space ! + + // Specific Character Set + ELEMENTS(0x0008,0x0005,"ISO_IR 100"), + // Patient's Name + ELEMENTS(0x0010,0x0010,""), + // Patient ID + ELEMENTS(0x0010,0x0020,""), + // Patient's Birthdate + ELEMENTS(0x0010,0x0030,""), + // Patient's Sex + ELEMENTS(0x0010,0x0040,""), + ELEMENTS(0xffff,0xffff,"") + }; + +ELEMENTS studyElem[]={ + ELEMENTS(0xfffe,0xe000,"0"), + // Offset of next directory record : to be computed later + ELEMENTS(0x0004,0x1400,"0"), + // Record in use flag : 65535(?) + ELEMENTS(0x0004,0x1410,"65535"), + // Offset of referenced lower-level dir entity : to be computed later + ELEMENTS(0x0004,0x1420,"0"), + // Directory Record Type + ELEMENTS(0x0004,0x1430,"STUDY "), // don't remove trailing space ! + + // Specific Character Set + ELEMENTS(0x0008,0x0005,"ISO_IR 100"), + // Study Date + ELEMENTS(0x0008,0x0020,""), + // Study Time + ELEMENTS(0x0008,0x0030,""), + // Accession Number + ELEMENTS(0x0008,0x0050,""), + // Study Description + ELEMENTS(0x0008,0x1030,""), + // Study Instance UID : may be forged later + ELEMENTS(0x0020,0x000d,""), + // Study ID : may be forged later + ELEMENTS(0x0020,0x0010,""), + ELEMENTS(0xffff,0xffff,"") +}; + + +ELEMENTS serieElem[]={ + ELEMENTS(0xfffe,0xe000,"0"), + // Offset of next directory record : to be computed later + ELEMENTS(0x0004,0x1400,"0"), + // Record in use flag : 65535(?) + ELEMENTS(0x0004,0x1410,"65535"), + // Offset of referenced lower-level dir entity : to be computed later + ELEMENTS(0x0004,0x1420,"0"), + // Directory Record Type + ELEMENTS(0x0004,0x1430,"SERIES"), // don't add trailing space ! + + // Specific Character Set + ELEMENTS(0x0008,0x0005,"ISO_IR 100"), + // Series Date + ELEMENTS(0x0008,0x0021,""), + // Series Time + ELEMENTS(0x0008,0x0031,""), + // Modality + ELEMENTS(0x0008,0x0060,""), + // Institution Name : may be forged later + ELEMENTS(0x0008,0x0080,""), + // Institution Address : may be forged later + ELEMENTS(0x0008,0x0081,""), + // Series Description : may be forged later + ELEMENTS(0x0008,0x103e,""), + // Series Instance UID : may be forged later + ELEMENTS(0x0020,0x000e,""), + // Series Number : may be forged later + ELEMENTS(0x0020,0x0011,"0"), + ELEMENTS(0xffff,0xffff,"") +}; + +ELEMENTS imageElem[]={ + ELEMENTS(0xfffe,0xe000,"0"), + // Offset of next directory record : to be computed later + ELEMENTS(0x0004,0x1400,"0"), + // Record in use flag : 65535(?) + ELEMENTS(0x0004,0x1410,"65535"), + // Offset of referenced lower-level dir entity : to be computed later + ELEMENTS(0x0004,0x1420,"0"), + // Directory Record Type + ELEMENTS(0x0004,0x1430,"IMAGE "), // don't remove trailing space ! + + // Referenced File ID : to be set later(relative File Name) + ELEMENTS(0x0004,0x1500,""), + // Referenced SOP Class UID in File : may be forged later + ELEMENTS(0x0004,0x1510,""), + // Referenced SOP Class UID in File : may be forged later + ELEMENTS(0x0004,0x1511,""), + // Referenced Transfer Syntax in File + ELEMENTS(0x0004,0x1512,""), + // Specific Character Set + ELEMENTS(0x0008,0x0005,"ISO_IR 100"), + // Image Type + ELEMENTS(0x0008,0x0008,""), + // SOP Class UID : to be set/forged later + ELEMENTS(0x0008,0x0016,""), + // SOP Instance UID : to be set/forged later + ELEMENTS(0x0008,0x0018,""), + // Content Date + ELEMENTS(0x0008,0x0023,""), + // Content Time + ELEMENTS(0x0008,0x0033,""), + // Referenced Image Sequence : to be set/forged later + ELEMENTS(0x0008,0x1040,""), + ELEMENTS(0xfffe,0xe000,"0"), + // Referenced SOP Class UID : to be set/forged later + ELEMENTS(0x0008,0x1150,""), + // Referenced SOP Instance UID : to be set/forged later + ELEMENTS(0x0008,0x1155,""), + // Image Number + ELEMENTS(0x0020,0x0013,"0"), + // Image Position Patient + ELEMENTS(0x0020,0x0032,"0"), + // Image Orientation(Patient) + ELEMENTS(0x0020,0x0037,"0"), + // Frame of Reference UID + ELEMENTS(0x0020,0x0052,"0"), + // Rows + ELEMENTS(0x0028,0x0010,"0"), + // Columns + ELEMENTS(0x0028,0x0011,"0"), + // Pixel Spacing + ELEMENTS(0x0028,0x0030,"0"), + // Calibration Image + ELEMENTS(0x0050,0x0004,"0"), + ELEMENTS(0xffff,0xffff,"") +}; +//----------------------------------------------------------------------------- +// Constructor / Destructor /* * \ingroup gdcmDicomDir * \brief * @param Filename * @param exception_on_error */ -gdcmDicomDir::gdcmDicomDir(std::string & FileName, +gdcmDicomDir::gdcmDicomDir(const char *FileName, 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"); - } + dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : entry list empty"); + dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory and create the DicomDir"); + + std::string path=FileName; + std::string file; + + int pos1=path.rfind("/"); + int pos2=path.rfind("\\"); + if(pos1>pos2) + path.resize(pos1); + else + path.resize(pos2); + NewDicomDir(path); + } + CreateDicomDir(); } - /* * \ingroup gdcmDicomDir * \brief @@ -48,29 +245,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 +272,58 @@ 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); + free(filePreamble); + WriteEntries(DICOMDIR,fp1); - - return true; + fclose(fp1); + + return true; } //----------------------------------------------------------------------------- // Protected +/* + * \ingroup gdcmDicomDir + * \brief + * @param + */ +void gdcmDicomDir::NewDicomDir(std::string path) +{ + gdcmDirList fileList(path,1); + ListHeader list; + gdcmHeader *header; + + listEntries.clear(); + + for(gdcmDirList::iterator it=fileList.begin(); + it!=fileList.end(); ++it) + { +// std::cout<<*it<c_str()); + if(header->IsReadable()) + list.push_back(header); + else + delete header; + } + + SetElements(path,list); +} //----------------------------------------------------------------------------- // Private @@ -123,13 +347,13 @@ 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::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 +464,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 +490,162 @@ 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) +{ + ELEMENTS *elemList; + guint16 tmpGr, tmpEl; + gdcmDictEntry *dictEntry; + gdcmHeaderEntry *entry; + std::string val; + + switch(type) + { + case GDCM_PATIENT: + elemList=patientElem; + break; + case GDCM_STUDY: + elemList=studyElem; + break; + case GDCM_SERIE: + elemList=serieElem; + break; + case GDCM_IMAGE: + elemList=imageElem; + break; + case GDCM_NONE: + elemList=metaElem; + break; + default: + return; + } + + for(int i=0;;i++) + { + tmpGr=elemList[i].group; + tmpEl=elemList[i].elem; + if(tmpGr==0xffff) + break; + + 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=elemList[i].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); + } +} + //----------------------------------------------------------------------------- diff --git a/src/gdcmDicomDir.h b/src/gdcmDicomDir.h index d5c70ffa..95a8d69c 100644 --- a/src/gdcmDicomDir.h +++ b/src/gdcmDicomDir.h @@ -1,4 +1,4 @@ -// gdcmDICOMDIR.h +// gdcmDicomDir.h //----------------------------------------------------------------------------- #ifndef GDCMDICOMDIR_H #define GDCMDICOMDIR_H @@ -9,6 +9,7 @@ //----------------------------------------------------------------------------- typedef std::list ListPatient; +typedef std::list ListHeader; //----------------------------------------------------------------------------- /* @@ -16,11 +17,11 @@ typedef std::list ListPatient; * \brief gdcmDicomDir defines an object representing a DICOMDIR in memory. * */ -class GDCM_EXPORT gdcmDicomDir: public gdcmParser +class GDCM_EXPORT gdcmDicomDir: public gdcmParser { public: gdcmDicomDir(ListTag *l, bool exception_on_error = false); - gdcmDicomDir(std::string &FileName,bool exception_on_error = false); + gdcmDicomDir(const char *FileName,bool exception_on_error = false); ~gdcmDicomDir(void); @@ -30,7 +31,6 @@ public: inline ListPatient &GetPatients() {return patients;}; bool Write(std::string fileName); - typedef enum { GDCM_NONE, @@ -40,6 +40,9 @@ public: GDCM_IMAGE, } gdcmDicomDirType; +protected: + void NewDicomDir(std::string path); + private: void CreateDicomDir(void); void AddObjectToEnd(gdcmDicomDirType type,ListTag::iterator begin,ListTag::iterator end); @@ -48,6 +51,9 @@ private: void AddSerieToEnd(ListTag::iterator begin,ListTag::iterator end); void AddImageToEnd(ListTag::iterator begin,ListTag::iterator end); + void SetElements(std::string &path,ListHeader &list); + void SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader *header); + ListPatient patients; }; diff --git a/src/gdcmDirList.cxx b/src/gdcmDirList.cxx new file mode 100644 index 00000000..096209fa --- /dev/null +++ b/src/gdcmDirList.cxx @@ -0,0 +1,138 @@ +// gdcmDirList.cxx +//----------------------------------------------------------------------------- +#include "gdcmDirList.h" + +#include +#include + +#ifdef GDCM_NO_ANSI_STRING_STREAM + #include + #define ostringstream ostrstream +#else + #include +#endif + +#ifdef _MSC_VER + #include + #include +#else + #include + #include +#endif + +//----------------------------------------------------------------------------- +const char gdcmDirList::SEPARATOR_X = '/'; +const char gdcmDirList::SEPARATOR_WIN = '\\'; +const std::string gdcmDirList::SEPARATOR = "/"; + +//----------------------------------------------------------------------------- +// Constructor / Destructor +/* + * \ingroup gdcmDirList + * \brief + * @param + */ +gdcmDirList::gdcmDirList(std::string dirName,bool recursive) +{ + name=dirName; + + NormalizePath(name); + Explore(name,recursive); +} + +/* + * \ingroup gdcmDirList + * \brief + * @param + */ +gdcmDirList::~gdcmDirList(void) +{ +} + +//----------------------------------------------------------------------------- +// Print + +//----------------------------------------------------------------------------- +// Public +/* + * \ingroup gdcmDirList + * \brief Get the directory name + * @param + */ +std::string gdcmDirList::GetDirName(void) +{ + return(name); +} + +//----------------------------------------------------------------------------- +// Protected + +//----------------------------------------------------------------------------- +// Private +/* + * \ingroup gdcmDirList + * \brief Add a SEPARATOR to the end of the directory name is necessary + * @param + */ +void gdcmDirList::NormalizePath(std::string &dirName) +{ + int size=dirName.size(); + if((dirName[size-1]!=SEPARATOR_X)&&(dirName[size-1]!=SEPARATOR_WIN)) + { + dirName+=SEPARATOR; + } +} + +/* + * \ingroup gdcmDirList + * \brief Explore a directory with possibility of recursion + * @param + */ +void gdcmDirList::Explore(std::string dirName,bool recursive) +{ + std::string fileName; + + NormalizePath(dirName); + +#ifdef _MSC_VER + WIN32_FIND_DATA fileData; + HANDLE hFile=FindFirstFile((dirName+"*").c_str(),&fileData); + int found=true; + + while( (hFile!=INVALID_HANDLE_VALUE) && (found) ) + { + fileName=fileData.cFileName; + if(fileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + { + if( (fileName!=".") && (fileName!="..") && (recursive) ) + Explore(dirName+fileName); + } + else + { + this->push_back(dirName+fileName); + } + + found=FindNextFile(hFile,&fileData); + } + +#else + struct dirent **namelist; + int n=scandir(dirName.c_str(), &namelist, 0, alphasort); + + for (int i= 0;i < n; i++) + { + fileName=namelist[i]->d_name; + if(namelist[i]->d_type==DT_DIR) + { + if( (fileName!=".") && (fileName!="..") && (recursive) ) + Explore(dirName+fileName); + } + else + { + this->push_back(dirName+fileName); + } + } +#endif +} + +//----------------------------------------------------------------------------- diff --git a/src/gdcmDirList.h b/src/gdcmDirList.h new file mode 100644 index 00000000..2dae2fcb --- /dev/null +++ b/src/gdcmDirList.h @@ -0,0 +1,32 @@ +// gdcmDir.h +//----------------------------------------------------------------------------- +#ifndef GDCMDIRLIST_H +#define GDCMDIRLIST_H + +#include "gdcmCommon.h" + +#include +#include + +//----------------------------------------------------------------------------- +class GDCM_EXPORT gdcmDirList: public std::list +{ +public : + gdcmDirList(std::string dirName,bool recursive=false); + virtual ~gdcmDirList(void); + + std::string GetDirName(void); + + static const char SEPARATOR_X; + static const char SEPARATOR_WIN; + static const std::string SEPARATOR; + +private : + void NormalizePath(std::string &dirName); + void Explore(std::string dirName,bool recursive=false); + + std::string name; +}; + +//----------------------------------------------------------------------------- +#endif diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx index 7b28ed42..5351d35b 100644 --- a/src/gdcmHeader.cxx +++ b/src/gdcmHeader.cxx @@ -792,6 +792,50 @@ void gdcmHeader::SetImageDataSize(size_t ImageDataSize) { SetEntryByNumber(content1, GrPixel, NumPixel); } +bool gdcmHeader::operator<(gdcmHeader &header) +{ + std::string s1,s2; + + // Patient Name + s1=this->GetEntryByNumber(0x0010,0x0010); + s2=header.GetEntryByNumber(0x0010,0x0010); + if(s1 < s2) + return(true); + else if(s1 > s2) + return(false); + else + { + // Patient ID + s1=this->GetEntryByNumber(0x0010,0x0020); + s2=header.GetEntryByNumber(0x0010,0x0020); + if (s1 < s2) + return(true); + else if (s1 > s2) + return(1); + else + { + // Study Instance UID + s1=this->GetEntryByNumber(0x0020,0x000d); + s2=header.GetEntryByNumber(0x0020,0x000d); + if (s1 < s2) + return(true); + else if(s1 > s2) + return(false); + else + { + // Serie Instance UID + s1=this->GetEntryByNumber(0x0020,0x000e); + s2=header.GetEntryByNumber(0x0020,0x000e); + if (s1 < s2) + return(true); + else if(s1 > s2) + return(false); + } + } + } + return(false); +} + //----------------------------------------------------------------------------- // Protected diff --git a/src/gdcmHeader.h b/src/gdcmHeader.h index 7c486e83..08b5388b 100644 --- a/src/gdcmHeader.h +++ b/src/gdcmHeader.h @@ -106,6 +106,8 @@ public: // Read (used in gdcmFile) void SetImageDataSize(size_t ExpectedSize); + bool operator<(gdcmHeader &header); + protected: int write(std::ostream&); int anonymize(std::ostream&); // FIXME : anonymize should be a friend ? diff --git a/src/gdcmHeaderHelper.cxx b/src/gdcmHeaderHelper.cxx index 27aafc3d..31fd9ab7 100644 --- a/src/gdcmHeaderHelper.cxx +++ b/src/gdcmHeaderHelper.cxx @@ -1,12 +1,13 @@ // gdcmHeaderHelper.cxx //----------------------------------------------------------------------------- #include "gdcmHeaderHelper.h" +#include "gdcmDirList.h" #include "gdcmUtil.h" //for debug #include #include -#ifdef _MSC_VER +/*#ifdef _MSC_VER #include int GetDir(std::string dPath, std::list &filenames) @@ -52,7 +53,7 @@ return true; } -#endif +#endif*/ //----------------------------------------------------------------------------- // gdcmHeaderHelper @@ -617,11 +618,10 @@ void gdcmSerieHeaderHelper::AddGdcmFile(gdcmHeaderHelper *file){ * \brief \todo */ void gdcmSerieHeaderHelper::SetDirectory(std::string dir){ - std::list filenames_list; - GetDir(dir, filenames_list); //OS specific + gdcmDirList filenames_list(dir); //OS specific - for(std::list::iterator it = filenames_list.begin(); it != - filenames_list.end(); it++) + for(gdcmDirList::iterator it = filenames_list.begin(); + it !=filenames_list.end(); it++) { gdcmHeaderHelper *file = new gdcmHeaderHelper( it->c_str() ); this->CoherentGdcmFileList.push_back( file ); diff --git a/src/gdcmImage.cxx b/src/gdcmImage.cxx index 30588f46..e47585aa 100644 --- a/src/gdcmImage.cxx +++ b/src/gdcmImage.cxx @@ -17,7 +17,14 @@ gdcmImage::~gdcmImage() // Print void gdcmImage::Print(std::ostream &os) { - os<<"IMAGE"<GetGroup()==0x0004) && ((*i)->GetElement()==0x1500) ) + os<<(*i)->GetValue(); + } + os<=0) { - (*i)->SetPrintLevel(printLevel); - (*i)->Print(os); + for(ListTag::iterator i=beginObj;i!=endObj;++i) + { + (*i)->SetPrintLevel(printLevel); + (*i)->Print(os); + } } } diff --git a/src/gdcmParser.cxx b/src/gdcmParser.cxx index df9f48f2..b442206b 100644 --- a/src/gdcmParser.cxx +++ b/src/gdcmParser.cxx @@ -353,10 +353,10 @@ FILE *gdcmParser::OpenFile(bool exception_on_error) return(fp); fclose(fp); - dbg.Verbose(0, "gdcmParser::gdcmParser not DICOM/ACR", filename.c_str()); + dbg.Verbose(0, "gdcmParser::OpenFile not DICOM/ACR", filename.c_str()); } else { - dbg.Verbose(0, "gdcmParser::gdcmParser cannot open file", filename.c_str()); + dbg.Verbose(0, "gdcmParser::OpenFile cannot open file", filename.c_str()); } return(NULL); } @@ -755,9 +755,7 @@ void *gdcmParser::LoadEntryVoidArea(guint16 Group, guint16 Elem) free(a); return NULL; } - cout << hex << Group << " " << Elem << "loaded" <SetPrintLevel(2); - Element->Print(); + return a; } diff --git a/src/win32/gdcmdll.dsp b/src/win32/gdcmdll.dsp index afb88cf2..b6215ebc 100644 --- a/src/win32/gdcmdll.dsp +++ b/src/win32/gdcmdll.dsp @@ -58,7 +58,7 @@ LINK32=link.exe # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy for test -PostBuild_Cmds=copy ..\..\lib\gdcmdll.dll ..\..\gdcmPython\ copy ..\..\lib\gdcmdll.dll ..\..\test\ copy Release\gdcmdll.lib ..\..\lib\ +PostBuild_Cmds=copy ..\..\lib\gdcmdll.dll ..\..\gdcmPython\ copy ..\..\lib\gdcmdll.dll ..\..\test\ copy Release\gdcmdll.lib ..\..\lib\ # End Special Build Tool !ELSEIF "$(CFG)" == "gdcmdll - Win32 Debug" @@ -90,7 +90,7 @@ LINK32=link.exe # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Copy for test -PostBuild_Cmds=copy ..\..\lib\gdcmdll.dll ..\..\gdcmPython\ copy ..\..\lib\gdcmdll.dll ..\..\test\ copy Debug\gdcmdll.lib ..\..\lib\ +PostBuild_Cmds=copy ..\..\lib\gdcmdll.dll ..\..\gdcmPython\ copy ..\..\lib\gdcmdll.dll ..\..\test\ copy Debug\gdcmdll.lib ..\..\lib\ # End Special Build Tool !ENDIF @@ -120,6 +120,10 @@ SOURCE=..\gdcmDictSet.cxx # End Source File # Begin Source File +SOURCE=..\gdcmDirList.cxx +# End Source File +# Begin Source File + SOURCE=..\gdcmException.cxx # End Source File # Begin Source File @@ -224,6 +228,10 @@ SOURCE=..\gdcmDictSet.h # End Source File # Begin Source File +SOURCE=..\gdcmDirList.h +# End Source File +# Begin Source File + SOURCE=..\gdcmException.h # End Source File # Begin Source File