X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmDicomDir.cxx;h=5b1b6e4904841fd0e34e5634e8649239c93cd62a;hb=31bb4e18ba6804c0d83fc34f11e89adc67271ea9;hp=d61e5c11a58efe4f2f8dcbc90e7b7f96e08c3dc4;hpb=fc8f963e32cfc0919160a3842d6da77e679fe320;p=gdcm.git diff --git a/src/gdcmDicomDir.cxx b/src/gdcmDicomDir.cxx index d61e5c11..5b1b6e49 100644 --- a/src/gdcmDicomDir.cxx +++ b/src/gdcmDicomDir.cxx @@ -1,39 +1,49 @@ // gdcmDicomDir.cxx //----------------------------------------------------------------------------- +#include +#include +#include +#include + +#ifdef _MSC_VER + #include +#else + #include +#endif + #include "gdcmDicomDir.h" #include "gdcmDicomDirStudy.h" #include "gdcmDicomDirSerie.h" #include "gdcmDicomDirImage.h" #include "gdcmDirList.h" #include "gdcmUtil.h" - -#include -#include - -#include -#include -#include +#include "gdcmDebug.h" +#include "gdcmGlobal.h" //----------------------------------------------------------------------------- // For full DICOMDIR description, see: // PS 3.3-2003, pages 731-750 //----------------------------------------------------------------------------- + + // Constructor / Destructor -/* - * \ingroup gdcmDicomDir - * \brief Constructor : Parses recursively the directory and creates the DicomDir - * \ or uses an already built DICOMDIR, depending on 'parseDir' value - * @param Name name of the root directory (parseDir = true) - * name of the DICOMDIR (parseDir = false) - * @param parseDir - true if user passed an entry point + +/** + * \brief Constructor Parses recursively the directory and creates the DicomDir + * or uses an already built DICOMDIR, depending on 'parseDir' value. + * @param FileName name + * - of the root directory (parseDir = true) + * - of the DICOMDIR (parseDir = false) + * @param parseDir boolean + * - true if user passed an entry point * and wants to explore recursively the directories - * - false if user passed an already built DICOMDIR file + * - false if user passed an already built DICOMDIR file * and wants to use it - * @param exception_on_error whether we want to throw an exception or not + * @param exception_on_error whether we want to throw an exception or not */ -gdcmDicomDir::gdcmDicomDir(const char *Name, bool parseDir, +gdcmDicomDir::gdcmDicomDir(const char *FileName, bool parseDir, bool exception_on_error): - gdcmParser(Name,exception_on_error,true) // true : enable SeQuences + gdcmParser(FileName,exception_on_error,true) // true : enable SeQuences { // que l'on ai passe un root directory ou un DICOMDIR // et quelle que soit la valeur de parseDir, @@ -54,7 +64,7 @@ gdcmDicomDir::gdcmDicomDir(const char *Name, bool parseDir, metaElems=NULL; -// gdcmParser already executed +// gdcmParser already executed // if user passed a root directory, sure we didn't get anything if( GetListEntry().begin()==GetListEntry().end() ) @@ -62,25 +72,30 @@ gdcmDicomDir::gdcmDicomDir(const char *Name, bool parseDir, // if parseDir == false, it should be tagged as an error dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : entry list empty"); - if(strlen(Name)==1 && Name[0]=='.') { // user passed '.' as Name + if(strlen(FileName)==1 && FileName[0]=='.') { // user passed '.' as Name // we get current directory name - char*dummy=(char*) malloc(1000); // TODO : check with Windoze - getcwd(dummy,(size_t)1000); + char* dummy= new char[1000]; + getcwd(dummy, (size_t)1000); SetFileName(dummy); // will be converted into a string - free(dummy); // no longer needed + delete[] dummy; // no longer needed } if(parseDir) { - dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory and create the DicomDir"); - ParseDirectory(); + dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory" + " and create the DicomDir"); + ParseDirectory(); } } - else + else { CreateDicomDir(); + CheckBoundaries(); // to maintain consistency between + // home-made gdcmDicomDir + // and the ones comming from a DICOMDIR file + } } -/* +/** * \ingroup gdcmDicomDir * \brief Constructor : creates an empty gdcmDicomDir * @param exception_on_error whether we want to throw an exception or not @@ -107,7 +122,7 @@ gdcmDicomDir::gdcmDicomDir(bool exception_on_error): } -/* +/** * \ingroup gdcmDicomDir * \brief Canonical destructor */ @@ -128,7 +143,7 @@ gdcmDicomDir::~gdcmDicomDir() //----------------------------------------------------------------------------- // Print -/* +/** * \ingroup gdcmDicomDir * \brief Canonical Printer */ @@ -148,7 +163,7 @@ void gdcmDicomDir::Print(std::ostream &os) //----------------------------------------------------------------------------- // Public -/* +/** * \ingroup gdcmDicomDir * \brief This predicate, based on hopefully reasonable heuristics, * decides whether or not the current header was properly parsed @@ -169,7 +184,7 @@ bool gdcmDicomDir::IsReadable(void) return(true); } -/* +/** * \ingroup gdcmDicomDir * \brief fills the whole structure, starting from a root Directory */ @@ -179,11 +194,12 @@ void gdcmDicomDir::ParseDirectory(void) CreateDicomDir(); } -/* +/** * \ingroup gdcmDicomDir * \brief Set the start method to call when the parsing of the directory starts * @param method Method to call * @param arg Argument to pass to the method + * @param argDelete Argument * \warning In python : the arg parameter isn't considered */ void gdcmDicomDir::SetStartMethod(gdcmMethod *method,void *arg,gdcmMethod *argDelete) @@ -196,7 +212,7 @@ void gdcmDicomDir::SetStartMethod(gdcmMethod *method,void *arg,gdcmMethod *argDe startMethodArgDelete=argDelete; } -/* +/** * \ingroup gdcmDicomDir * \brief Set the method to delete the argument * The argument is destroyed when the method is changed or when the @@ -208,11 +224,12 @@ void gdcmDicomDir::SetStartMethodArgDelete(gdcmMethod *method) startMethodArgDelete=method; } -/* +/** * \ingroup gdcmDicomDir * \brief Set the progress method to call when the parsing of the directory progress * @param method Method to call * @param arg Argument to pass to the method + * @param argDelete Argument * \warning In python : the arg parameter isn't considered */ void gdcmDicomDir::SetProgressMethod(gdcmMethod *method,void *arg,gdcmMethod *argDelete) @@ -225,7 +242,7 @@ void gdcmDicomDir::SetProgressMethod(gdcmMethod *method,void *arg,gdcmMethod *ar progressMethodArgDelete=argDelete; } -/* +/** * \ingroup gdcmDicomDir * \brief Set the method to delete the argument * The argument is destroyed when the method is changed or when the @@ -237,14 +254,15 @@ void gdcmDicomDir::SetProgressMethodArgDelete(gdcmMethod *method) progressMethodArgDelete=method; } -/* +/** * \ingroup gdcmDicomDir * \brief Set the end method to call when the parsing of the directory ends * @param method Method to call * @param arg Argument to pass to the method + * @param argDelete Argument * \warning In python : the arg parameter isn't considered */ -void gdcmDicomDir::SetEndMethod(gdcmMethod *method,void *arg,gdcmMethod *argDelete) +void gdcmDicomDir::SetEndMethod(gdcmMethod *method, void *arg, gdcmMethod *argDelete) { if((endArg)&&(endMethodArgDelete)) endMethodArgDelete(endArg); @@ -254,7 +272,7 @@ void gdcmDicomDir::SetEndMethod(gdcmMethod *method,void *arg,gdcmMethod *argDele endMethodArgDelete=argDelete; } -/* +/** * \ingroup gdcmDicomDir * \brief Set the method to delete the argument * The argument is destroyed when the method is changed or when the class @@ -289,27 +307,23 @@ bool gdcmDicomDir::Write(std::string fileName) return(false); } - char * filePreamble; - filePreamble=(char*)calloc(128,1); + char * filePreamble = new char[128]; fwrite(filePreamble,128,1,fp1); fwrite("DICM",4,1,fp1); - free(filePreamble); - //UpdateDirectoryRecordSequenceLength(); // a reecrire en utilisant - // la structure arborescente JPR - WriteDicomDirEntries(fp1); + delete[] filePreamble; + UpdateDirectoryRecordSequenceLength(); + WriteEntries(fp1); fclose(fp1); return true; } /** - * \ingroup gdcmParser - * \brief writes on disc according to the DICOMDIR format - * using the tree-like structure + * \brief Writes in a file using the tree-like structure. * @param _fp already open file pointer */ -void gdcmDicomDir::WriteDicomDirEntries(FILE *_fp) +void gdcmDicomDir::WriteEntries(FILE *_fp) { // TODO (?) tester les echecs en ecriture // (apres chaque fwrite, dans le WriteEntry) @@ -323,28 +337,28 @@ void gdcmDicomDir::WriteDicomDirEntries(FILE *_fp) ptrMeta= GetDicomDirMeta(); for(i=ptrMeta->debut();i!=ptrMeta->fin();++i) { - WriteEntry(*i,_fp,DICOMDIR); + WriteEntry(*i,_fp, ExplicitVR); } itPatient = GetDicomDirPatients().begin(); while ( itPatient != GetDicomDirPatients().end() ) { for(i=(*itPatient)->debut();i!=(*itPatient)->fin();++i) { - WriteEntry(*i,_fp,DICOMDIR); + WriteEntry(*i,_fp, ExplicitVR); } itStudy = ((*itPatient)->GetDicomDirStudies()).begin(); while (itStudy != (*itPatient)->GetDicomDirStudies().end() ) { for(i=(*itStudy)->debut();i!=(*itStudy)->fin();++i) { - WriteEntry(*i,_fp,DICOMDIR); + WriteEntry(*i,_fp, ExplicitVR); } itSerie = ((*itStudy)->GetDicomDirSeries()).begin(); while (itSerie != (*itStudy)->GetDicomDirSeries().end() ) { for(i=(*itSerie)->debut();i!=(*itSerie)->fin();++i) { - WriteEntry(*i,_fp,DICOMDIR); + WriteEntry(*i,_fp, ExplicitVR); } itImage = ((*itSerie)->GetDicomDirImages()).begin(); while (itImage != (*itSerie)->GetDicomDirImages().end() ) { for(i=(*itImage)->debut();i!=(*itImage)->fin();++i) { - WriteEntry(*i,_fp,DICOMDIR); + WriteEntry(*i,_fp, ExplicitVR); } ++itImage; } @@ -359,7 +373,7 @@ void gdcmDicomDir::WriteDicomDirEntries(FILE *_fp) //----------------------------------------------------------------------------- // Protected -/* +/** * \ingroup gdcmDicomDir * \brief create a gdcmHeader-like chained list from a root Directory * @param path entry point of the tree-like structure @@ -397,13 +411,52 @@ void gdcmDicomDir::CreateDicomDirChainedList(std::string path) std::sort(list.begin(),list.end(),gdcmDicomDir::HeaderLessThan); std::string tmp=fileList.GetDirName(); + //for each Header of the chained list, add/update the Patient/Study/Serie/Image info SetElements(tmp,list); - + CallEndMethod(); } -/* +/** + * \ingroup gdcmDicomDir + * \brief modifies the limits of a gdcmObject, created from a DICOMDIR file + */ + +void gdcmDicomDir::CheckBoundaries() +{ + ListDicomDirPatient::iterator itPatient; + ListDicomDirStudy::iterator itStudy; + ListDicomDirSerie::iterator itSerie; + ListDicomDirImage::iterator itImage; + ListTag::iterator i,j; + + GetDicomDirMeta()->ResetBoundaries(0); + + itPatient = GetDicomDirPatients().begin(); + while ( itPatient != GetDicomDirPatients().end() ) { + (*itPatient)->ResetBoundaries(1); + itStudy = ((*itPatient)->GetDicomDirStudies()).begin(); + while (itStudy != (*itPatient)->GetDicomDirStudies().end() ) { + (*itStudy)->ResetBoundaries(1); + itSerie = ((*itStudy)->GetDicomDirSeries()).begin(); + while (itSerie != (*itStudy)->GetDicomDirSeries().end() ) { + (*itSerie)->ResetBoundaries(1); + itImage = ((*itSerie)->GetDicomDirImages()).begin(); + while (itImage != (*itSerie)->GetDicomDirImages().end() ) { + (*itImage)->ResetBoundaries(1); + ++itImage; + } + ++itSerie; + } + ++itStudy; + } + ++itPatient; + } +} + + +/** * \ingroup gdcmDicomDir * \brief adds a new Patient to a partially created DICOMDIR */ @@ -432,9 +485,9 @@ gdcmDicomDirPatient * gdcmDicomDir::NewPatient(void) { entry->SetValue(it->value); if(dictEntry->GetGroup()==0xfffe) - { - entry->SetLength(entry->GetValue().length()); - } + { + entry->SetLength(entry->GetValue().length()); + } else if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") ) { entry->SetLength(4); @@ -466,7 +519,7 @@ gdcmDicomDirPatient * gdcmDicomDir::NewPatient(void) { return p; } -/* +/** * \ingroup gdcmDicomDir * \brief CallStartMethod */ @@ -477,7 +530,7 @@ void gdcmDicomDir::CallStartMethod(void) if(startMethod) startMethod(startArg); } -/* +/** * \ingroup gdcmDicomDir * \brief CallProgressMethod */ @@ -486,7 +539,7 @@ void gdcmDicomDir::CallProgressMethod(void) if(progressMethod) progressMethod(progressArg); } -/* +/** * \ingroup gdcmDicomDir * \brief CallEndMethod */ @@ -499,7 +552,7 @@ void gdcmDicomDir::CallEndMethod(void) //----------------------------------------------------------------------------- // Private -/* +/** * \ingroup gdcmDicomDir * \brief create a 'gdcmDicomDir' from a DICOMDIR gdcmHeader */ @@ -559,12 +612,12 @@ void gdcmDicomDir::CreateDicomDir() if(begin!=end) AddObjectToEnd(type,begin,--end2); } -/* +/** * \ingroup gdcmDicomDir * \brief AddObjectToEnd * @param type - * @param begin - * @param end + * @param begin iterator on the first HeaderEntry within the chained List + * @param end iterator on the last HeaderEntry within the chained List */ void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,ListTag::iterator begin,ListTag::iterator end) { @@ -588,14 +641,17 @@ void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,ListTag::iterator begin, case gdcmDicomDir::GDCM_DICOMDIR_IMAGE: AddDicomDirImageToEnd(begin,end); break; + case gdcmDicomDir::GDCM_DICOMDIR_NONE: + AddDicomDirImageToEnd(begin,end); //FIXME + break; } } -/* +/** * \ingroup gdcmDicomDir * \brief Well ... Not realy to end, there is only one occurence - * @param begin - * @param end + * @param begin iterator on the first HeaderEntry within the chained List + * @param end iterator on the last HeaderEntry within the chained List */ void gdcmDicomDir::AddDicomDirMetaToEnd(ListTag::iterator begin,ListTag::iterator end) { @@ -604,22 +660,22 @@ void gdcmDicomDir::AddDicomDirMetaToEnd(ListTag::iterator begin,ListTag::iterato metaElems = new gdcmDicomDirMeta(begin,end,&tagHT,&listEntries); } -/* +/** * \ingroup gdcmDicomDir * \brief AddDicomDirPatientToEnd - * @param begin - * @param end + * @param begin iterator on the first HeaderEntry within the chained List + * @param end iterator on the last HeaderEntry within the chained List */ void gdcmDicomDir::AddDicomDirPatientToEnd(ListTag::iterator begin,ListTag::iterator end) { patients.push_back(new gdcmDicomDirPatient(begin,end,&tagHT, &listEntries)); } -/* +/** * \ingroup gdcmDicomDir * \brief AddDicomDirStudyToEnd - * @param begin - * @param end + * @param begin iterator on the first HeaderEntry within the chained List + * @param end iterator on the last HeaderEntry within the chained List */ void gdcmDicomDir::AddDicomDirStudyToEnd(ListTag::iterator begin,ListTag::iterator end) { @@ -630,11 +686,11 @@ void gdcmDicomDir::AddDicomDirPatientToEnd(ListTag::iterator begin,ListTag::iter (*itp)->AddDicomDirStudy(new gdcmDicomDirStudy(begin,end,&tagHT, &listEntries)); } } -/* +/** * \ingroup gdcmDicomDir * \brief AddDicomDirSerieToEnd - * @param begin - * @param end + * @param begin iterator on the first HeaderEntry within the chained List + * @param end iterator on the last HeaderEntry within the chained List */ void gdcmDicomDir::AddDicomDirSerieToEnd(ListTag::iterator begin,ListTag::iterator end) { @@ -652,11 +708,11 @@ void gdcmDicomDir::AddDicomDirSerieToEnd(ListTag::iterator begin,ListTag::iterat } } -/* +/** * \ingroup gdcmDicomDir * \brief AddDicomDirImageToEnd - * @param begin - * @param end + * @param begin iterator on the first HeaderEntry within the chained List + * @param end iterator on the last HeaderEntry within the chained List */ void gdcmDicomDir::AddDicomDirImageToEnd(ListTag::iterator begin,ListTag::iterator end) { @@ -680,7 +736,7 @@ void gdcmDicomDir::AddDicomDirSerieToEnd(ListTag::iterator begin,ListTag::iterat } } -/* +/** * \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 @@ -732,7 +788,7 @@ void gdcmDicomDir::SetElements(std::string &path, ListHeader &list) } } -/* +/** * \ingroup gdcmDicomDir * \brief adds to the HTable and at the end of the Chained List * the gdcmEntries (Dicom Elements) corresponding to the given type @@ -843,13 +899,19 @@ void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader //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; @@ -869,7 +931,8 @@ void gdcmDicomDir::UpdateDirectoryRecordSequenceLength() { offset += 4; // delimiters don't have a value. } } - bool res=SetEntryLengthByNumber(offset, 0x0004, 0x1220); // Hope there is no dupps. + //bool res=SetEntryLengthByNumber(offset, 0x0004, 0x1220); // Hope there is no dupps. + SetEntryLengthByNumber(offset, 0x0004, 0x1220); // Hope there is no dupps. return; }