2 //-----------------------------------------------------------------------------
3 #include "gdcmDicomDir.h"
7 #include "gdcmDirList.h"
13 #include <sys/types.h>
16 //-----------------------------------------------------------------------------
17 // Constructor / Destructor
19 * \ingroup gdcmDicomDir
22 * @param exception_on_error
24 gdcmDicomDir::gdcmDicomDir(const char *FileName, bool parseDir,
25 bool exception_on_error):
26 gdcmParser(FileName,exception_on_error,true)
28 if( GetListEntry().begin()==GetListEntry().end() )
30 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : entry list empty");
34 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory and create the DicomDir");
43 * \ingroup gdcmDicomDir
45 * @param exception_on_error
47 /*gdcmDicomDir::gdcmDicomDir(ListTag *l,
48 bool exception_on_error):
49 gdcmParser(exception_on_error )
56 * \ingroup gdcmDicomDir
57 * \brief Canonical destructor
59 gdcmDicomDir::~gdcmDicomDir()
61 for(ListPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
67 //-----------------------------------------------------------------------------
69 void gdcmDicomDir::Print(std::ostream &os)
71 for(ListPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
73 (*cc)->SetPrintLevel(printLevel);
78 //-----------------------------------------------------------------------------
81 * \ingroup gdcmDicomDir
82 * \brief writes on disc a DICOMDIR
83 * \ warning does NOT add the missing elements in the header :
84 * \ it's up to the user doing it !
85 * @param fileName file to be written to
88 bool gdcmDicomDir::Write(std::string fileName)
92 fp1=fopen(fileName.c_str(),"wb");
95 printf("Failed to open(write) File [%s] \n",fileName.c_str());
100 filePreamble=(char*)calloc(128,1);
101 fwrite(filePreamble,128,1,fp1);
102 fwrite("DICM",4,1,fp1);
105 WriteEntries(fp1,DICOMDIR);
112 void gdcmDicomDir::ParseDirectory(void)
114 NewDicomDir(GetPath());
118 //-----------------------------------------------------------------------------
121 * \ingroup gdcmDicomDir
125 void gdcmDicomDir::NewDicomDir(std::string path)
127 gdcmDirList fileList(path,1);
134 for(gdcmDirList::iterator it=fileList.begin();
135 it!=fileList.end(); ++it)
137 header=new gdcmHeader(it->c_str());
138 if(header->IsReadable())
139 list.push_back(header);
144 std::sort(list.begin(),list.end(),gdcmDicomDir::HeaderLessThan);
146 SetElements(path,list);
150 * \ingroup gdcmDicomDir
151 * \brief Get the dicom dir path
154 std::string gdcmDicomDir::GetPath(void)
156 std::string path=GetFileName();
158 int pos1=path.rfind("/");
159 int pos2=path.rfind("\\");
168 //-----------------------------------------------------------------------------
171 * \ingroup gdcmDicomDir
175 void gdcmDicomDir::CreateDicomDir()
177 // The list is parsed. When a tag is found :
178 // 1 - we save the beginning iterator
179 // 2 - we continue to parse
180 // 3 - we find an other tag
181 // + we create the object for the precedent tag
184 gdcmDicomDirType type=gdcmDicomDir::GDCM_NONE;
185 ListTag::iterator begin;
186 ListTag::iterator end;
188 begin=listEntries.begin();
190 for(ListTag::iterator i=listEntries.begin();i !=listEntries.end();++i)
192 std::string v=(*i)->GetValue();
196 AddObjectToEnd(type,begin,end);
198 type=gdcmDicomDir::GDCM_PATIENT;
205 AddObjectToEnd(type,begin,end);
207 type=gdcmDicomDir::GDCM_STUDY;
214 AddObjectToEnd(type,begin,end);
216 type=gdcmDicomDir::GDCM_SERIE;
223 AddObjectToEnd(type,begin,end);
225 type=gdcmDicomDir::GDCM_IMAGE;
230 end=GetListEntry().end();
231 AddObjectToEnd(type,begin,end);
234 * \ingroup gdcmDicomDir
238 void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,ListTag::iterator begin,ListTag::iterator end)
245 case gdcmDicomDir::GDCM_PATIENT:
246 AddPatientToEnd(begin,end);
248 case gdcmDicomDir::GDCM_STUDY:
249 AddStudyToEnd(begin,end);
251 case gdcmDicomDir::GDCM_SERIE:
252 AddSerieToEnd(begin,end);
254 case gdcmDicomDir::GDCM_IMAGE:
255 AddImageToEnd(begin,end);
261 * \ingroup gdcmDicomDir
265 void gdcmDicomDir::AddPatientToEnd(ListTag::iterator begin,ListTag::iterator end)
267 patients.push_back(new gdcmPatient(begin,end));
271 * \ingroup gdcmDicomDir
275 void gdcmDicomDir::AddStudyToEnd(ListTag::iterator begin,ListTag::iterator end)
277 if(patients.size()>0)
279 ListPatient::iterator itp=patients.end();
281 (*itp)->AddStudy(new gdcmStudy(begin,end));
285 * \ingroup gdcmDicomDir
289 void gdcmDicomDir::AddSerieToEnd(ListTag::iterator begin,ListTag::iterator end)
291 if(patients.size()>0)
293 ListPatient::iterator itp=patients.end();
296 if((*itp)->GetStudies().size()>0)
298 ListStudy::iterator itst=(*itp)->GetStudies().end();
300 (*itst)->AddSerie(new gdcmSerie(begin,end));
306 * \ingroup gdcmDicomDir
310 void gdcmDicomDir::AddImageToEnd(ListTag::iterator begin,ListTag::iterator end)
312 if(patients.size()>0)
314 ListPatient::iterator itp=patients.end();
317 if((*itp)->GetStudies().size()>0)
319 ListStudy::iterator itst=(*itp)->GetStudies().end();
322 if((*itst)->GetSeries().size()>0)
324 ListSerie::iterator its=(*itst)->GetSeries().end();
326 (*its)->AddImage(new gdcmImage(begin,end));
333 * \ingroup gdcmDicomDir
337 void gdcmDicomDir::SetElements(std::string &path,ListHeader &list)
339 std::string patPrevName="", patPrevID="";
340 std::string studPrevInstanceUID="", studPrevID="";
341 std::string serPrevInstanceUID="", serPrevID="";
343 std::string patCurName, patCurID;
344 std::string studCurInstanceUID, studCurID;
345 std::string serCurInstanceUID, serCurID;
347 SetElement(path,GDCM_NONE,NULL);
349 ListTag::iterator debPat=listEntries.begin();
350 for(ListHeader::iterator it=list.begin();it!=list.end();++it)
352 // get the current file characteristics
353 patCurName=(*it)->GetEntryByNumber(0x0010,0x0010);
354 patCurID=(*it)->GetEntryByNumber(0x0010,0x0011);
355 studCurInstanceUID=(*it)->GetEntryByNumber(0x0020,0x000d);
356 studCurID=(*it)->GetEntryByNumber(0x0020,0x0010);
357 serCurInstanceUID=(*it)->GetEntryByNumber(0x0020,0x000e);
358 serCurID=(*it)->GetEntryByNumber(0x0020,0x0011);
360 if(patCurName!=patPrevName || patCurID!=patPrevID)
361 SetElement(path,GDCM_PATIENT,*it);
363 // if new Study Deal with 'STUDY' Elements
364 if(studCurInstanceUID!=studPrevInstanceUID || studCurID!=studPrevID)
365 SetElement(path,GDCM_STUDY,*it);
367 // if new Serie Deal with 'SERIE' Elements
368 if(serCurInstanceUID!=serPrevInstanceUID || serCurID!=serPrevID)
370 SetElement(path,GDCM_SERIE,*it);
373 // Always Deal with 'IMAGE' Elements
374 SetElement(path,GDCM_IMAGE,*it);
376 patPrevName=patCurName;
378 studPrevInstanceUID=studCurInstanceUID;
379 studPrevID=studCurID;
380 serPrevInstanceUID=serCurInstanceUID;
386 * \ingroup gdcmDicomDir
390 void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader *header)
392 std::list<gdcmElement> elemList;
393 std::list<gdcmElement>::iterator it;
394 guint16 tmpGr, tmpEl;
395 gdcmDictEntry *dictEntry;
396 gdcmHeaderEntry *entry;
402 elemList=gdcmGlobal::GetDicomDirElements()->GetPatientElements();
405 elemList=gdcmGlobal::GetDicomDirElements()->GetStudyElements();
408 elemList=gdcmGlobal::GetDicomDirElements()->GetSerieElements();
411 elemList=gdcmGlobal::GetDicomDirElements()->GetImageElements();
414 elemList=gdcmGlobal::GetDicomDirElements()->GetMetaElements();
420 for(it=elemList.begin();it!=elemList.end();++it)
425 dictEntry=GetPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
426 entry=new gdcmHeaderEntry(dictEntry);
427 entry->SetOffset(0); // just to avoid missprinting
430 val=header->GetEntryByNumber(tmpGr,tmpEl);
434 if(val==GDCM_UNFOUND)
436 if((tmpGr==0x0004) &&(tmpEl==0x1130) )
438 // TODO force the *end* File Name(remove path)
441 else if( (tmpGr==0x0004) && (tmpEl==0x1500) ) // Only used for image
443 if(header->GetFileName().substr(0,path.length())!=path)
445 dbg.Verbose(0, "gdcmDicomDir::SetElement : the base path of file name is incorrect");
446 val=header->GetFileName();
449 val=&(header->GetFileName()[path.length()]);
456 entry->SetValue(val);
460 if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") )
464 else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") )
468 else if(dictEntry->GetVR()=="SQ")
470 entry->SetLength(0xffffffff);
474 entry->SetLength(entry->GetValue().length());
478 listEntries.push_back(entry);
482 bool gdcmDicomDir::HeaderLessThan(gdcmHeader *header1,gdcmHeader *header2)
484 return(*header1<*header2);
487 //-----------------------------------------------------------------------------