2 //-----------------------------------------------------------------------------
3 #include "gdcmDicomDir.h"
7 #include "gdcmDirList.h"
12 #include <sys/types.h>
15 //-----------------------------------------------------------------------------
16 // Constructor / Destructor
18 * \ingroup gdcmDicomDir
21 * @param exception_on_error
23 gdcmDicomDir::gdcmDicomDir(const char *FileName, bool parseDir,
24 bool exception_on_error):
25 gdcmParser(FileName,exception_on_error,true)
27 if( GetListEntry().begin()==GetListEntry().end() )
29 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : entry list empty");
33 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory and create the DicomDir");
42 * \ingroup gdcmDicomDir
44 * @param exception_on_error
46 /*gdcmDicomDir::gdcmDicomDir(ListTag *l,
47 bool exception_on_error):
48 gdcmParser(exception_on_error )
55 * \ingroup gdcmDicomDir
56 * \brief Canonical destructor
58 gdcmDicomDir::~gdcmDicomDir()
60 for(ListPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
66 //-----------------------------------------------------------------------------
68 void gdcmDicomDir::Print(std::ostream &os)
70 for(ListPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
72 (*cc)->SetPrintLevel(printLevel);
77 //-----------------------------------------------------------------------------
80 * \ingroup gdcmDicomDir
81 * \brief writes on disc a DICOMDIR
82 * \ warning does NOT add the missing elements in the header :
83 * \ it's up to the user doing it !
84 * @param fileName file to be written to
87 bool gdcmDicomDir::Write(std::string fileName)
91 fp1=fopen(fileName.c_str(),"wb");
94 printf("Failed to open(write) File [%s] \n",fileName.c_str());
99 filePreamble=(char*)calloc(128,1);
100 fwrite(filePreamble,128,1,fp1);
101 fwrite("DICM",4,1,fp1);
104 WriteEntries(fp1,DICOMDIR);
111 void gdcmDicomDir::ParseDirectory(void)
113 NewDicomDir(GetPath());
117 //-----------------------------------------------------------------------------
120 * \ingroup gdcmDicomDir
124 void gdcmDicomDir::NewDicomDir(std::string path)
126 gdcmDirList fileList(path,1);
133 for(gdcmDirList::iterator it=fileList.begin();
134 it!=fileList.end(); ++it)
136 // std::cout<<*it<<std::endl;
137 header=new gdcmHeader(it->c_str());
138 if(header->IsReadable())
139 list.push_back(header);
144 SetElements(path,list);
148 * \ingroup gdcmDicomDir
149 * \brief Get the dicom dir path
152 std::string gdcmDicomDir::GetPath(void)
154 std::string path=GetFileName();
156 int pos1=path.rfind("/");
157 int pos2=path.rfind("\\");
166 //-----------------------------------------------------------------------------
169 * \ingroup gdcmDicomDir
173 void gdcmDicomDir::CreateDicomDir()
175 // The list is parsed. When a tag is found :
176 // 1 - we save the beginning iterator
177 // 2 - we continue to parse
178 // 3 - we find an other tag
179 // + we create the object for the precedent tag
182 gdcmDicomDirType type=gdcmDicomDir::GDCM_NONE;
183 ListTag::iterator begin;
184 ListTag::iterator end;
186 begin=listEntries.begin();
188 for(ListTag::iterator i=listEntries.begin();i !=listEntries.end();++i)
190 // std::cout << std::hex <<(*i)->GetGroup() <<
191 // " " <<(*i)->GetElement() << endl;
193 std::string v=(*i)->GetValue();
196 // std::cout<<"PATIENT"<<std::endl;
198 AddObjectToEnd(type,begin,end);
200 type=gdcmDicomDir::GDCM_PATIENT;
206 // std::cout<<"STUDY"<<std::endl;
208 AddObjectToEnd(type,begin,end);
210 type=gdcmDicomDir::GDCM_STUDY;
216 // std::cout<<"SERIES"<<std::endl;
218 AddObjectToEnd(type,begin,end);
220 type=gdcmDicomDir::GDCM_SERIE;
226 // std::cout<<"IMAGE"<<std::endl;
228 AddObjectToEnd(type,begin,end);
230 type=gdcmDicomDir::GDCM_IMAGE;
235 end=GetListEntry().end();
236 AddObjectToEnd(type,begin,end);
239 * \ingroup gdcmDicomDir
243 void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,ListTag::iterator begin,ListTag::iterator end)
250 case gdcmDicomDir::GDCM_PATIENT:
251 AddPatientToEnd(begin,end);
253 case gdcmDicomDir::GDCM_STUDY:
254 AddStudyToEnd(begin,end);
256 case gdcmDicomDir::GDCM_SERIE:
257 AddSerieToEnd(begin,end);
259 case gdcmDicomDir::GDCM_IMAGE:
260 AddImageToEnd(begin,end);
266 * \ingroup gdcmDicomDir
270 void gdcmDicomDir::AddPatientToEnd(ListTag::iterator begin,ListTag::iterator end)
272 patients.push_back(new gdcmPatient(begin,end));
276 * \ingroup gdcmDicomDir
280 void gdcmDicomDir::AddStudyToEnd(ListTag::iterator begin,ListTag::iterator end)
282 if(patients.size()>0)
284 ListPatient::iterator itp=patients.end();
286 (*itp)->AddStudy(new gdcmStudy(begin,end));
290 * \ingroup gdcmDicomDir
294 void gdcmDicomDir::AddSerieToEnd(ListTag::iterator begin,ListTag::iterator end)
296 if(patients.size()>0)
298 ListPatient::iterator itp=patients.end();
301 if((*itp)->GetStudies().size()>0)
303 ListStudy::iterator itst=(*itp)->GetStudies().end();
305 (*itst)->AddSerie(new gdcmSerie(begin,end));
311 * \ingroup gdcmDicomDir
315 void gdcmDicomDir::AddImageToEnd(ListTag::iterator begin,ListTag::iterator end)
317 if(patients.size()>0)
319 ListPatient::iterator itp=patients.end();
322 if((*itp)->GetStudies().size()>0)
324 ListStudy::iterator itst=(*itp)->GetStudies().end();
327 if((*itst)->GetSeries().size()>0)
329 ListSerie::iterator its=(*itst)->GetSeries().end();
331 (*its)->AddImage(new gdcmImage(begin,end));
338 * \ingroup gdcmDicomDir
342 void gdcmDicomDir::SetElements(std::string &path,ListHeader &list)
344 std::string patPrevName="", patPrevID="";
345 std::string studPrevInstanceUID="", studPrevID="";
346 std::string serPrevInstanceUID="", serPrevID="";
348 std::string patCurName, patCurID;
349 std::string studCurInstanceUID, studCurID;
350 std::string serCurInstanceUID, serCurID;
352 SetElement(path,GDCM_NONE,NULL);
354 ListTag::iterator debPat=listEntries.begin();
355 for(ListHeader::iterator it=list.begin();it!=list.end();++it)
357 // get the current file characteristics
358 patCurName=(*it)->GetEntryByNumber(0x0010,0x0010);
359 patCurID=(*it)->GetEntryByNumber(0x0010,0x0011);
360 studCurInstanceUID=(*it)->GetEntryByNumber(0x0020,0x000d);
361 studCurID=(*it)->GetEntryByNumber(0x0020,0x0010);
362 serCurInstanceUID=(*it)->GetEntryByNumber(0x0020,0x000e);
363 serCurID=(*it)->GetEntryByNumber(0x0020,0x0011);
365 if(patCurName!=patPrevName || patCurID!=patPrevID)
366 SetElement(path,GDCM_PATIENT,*it);
368 // if new Study Deal with 'STUDY' Elements
369 if(studCurInstanceUID!=studPrevInstanceUID || studCurID!=studPrevID)
370 SetElement(path,GDCM_STUDY,*it);
372 // if new Serie Deal with 'SERIE' Elements
373 if(serCurInstanceUID!=serPrevInstanceUID || serCurID!=serPrevID)
375 SetElement(path,GDCM_SERIE,*it);
378 // Always Deal with 'IMAGE' Elements
379 SetElement(path,GDCM_IMAGE,*it);
381 patPrevName=patCurName;
383 studPrevInstanceUID=studCurInstanceUID;
384 studPrevID=studCurID;
385 serPrevInstanceUID=serCurInstanceUID;
391 * \ingroup gdcmDicomDir
395 void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader *header)
397 std::list<gdcmElement> elemList;
398 std::list<gdcmElement>::iterator it;
399 guint16 tmpGr, tmpEl;
400 gdcmDictEntry *dictEntry;
401 gdcmHeaderEntry *entry;
407 elemList=gdcmGlobal::GetDicomDirElements()->GetPatientElements();
410 elemList=gdcmGlobal::GetDicomDirElements()->GetStudyElements();
413 elemList=gdcmGlobal::GetDicomDirElements()->GetSerieElements();
416 elemList=gdcmGlobal::GetDicomDirElements()->GetImageElements();
419 elemList=gdcmGlobal::GetDicomDirElements()->GetMetaElements();
425 for(it=elemList.begin();it!=elemList.end();++it)
430 dictEntry=GetPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
431 entry=new gdcmHeaderEntry(dictEntry);
432 entry->SetOffset(0); // just to avoid missprinting
435 val=header->GetEntryByNumber(tmpGr,tmpEl);
439 if(val==GDCM_UNFOUND)
441 if((tmpGr==0x0004) &&(tmpEl==0x1130) )
443 // TODO force the *end* File Name(remove path)
446 else if( (tmpGr==0x0004) && (tmpEl==0x1500) ) // Only used for image
448 if(header->GetFileName().substr(0,path.length())!=path)
450 dbg.Verbose(0, "gdcmDicomDir::SetElement : the base path of file name is incorrect");
451 val=header->GetFileName();
454 val=&(header->GetFileName()[path.length()]);
461 entry->SetValue(val);
465 if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") )
469 else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") )
473 else if(dictEntry->GetVR()=="SQ")
475 entry->SetLength(0xffffffff);
479 entry->SetLength(entry->GetValue().length());
483 listEntries.push_back(entry);
487 //-----------------------------------------------------------------------------