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,
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");
30 dbg.Verbose(0, "gdcmDicomDir::gdcmDicomDir : Parse directory and create the DicomDir");
32 std::string path=FileName;
35 int pos1=path.rfind("/");
36 int pos2=path.rfind("\\");
48 * \ingroup gdcmDicomDir
50 * @param exception_on_error
52 gdcmDicomDir::gdcmDicomDir(ListTag *l,
53 bool exception_on_error):
54 gdcmParser(exception_on_error )
61 * \ingroup gdcmDicomDir
62 * \brief Canonical destructor
64 gdcmDicomDir::~gdcmDicomDir()
66 for(ListPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
72 //-----------------------------------------------------------------------------
74 void gdcmDicomDir::Print(std::ostream &os)
76 for(ListPatient::iterator cc=patients.begin();cc!=patients.end();++cc)
78 (*cc)->SetPrintLevel(printLevel);
83 //-----------------------------------------------------------------------------
86 * \ingroup gdcmDicomDir
87 * \brief writes on disc a DICOMDIR
88 * \ warning does NOT add the missing elements in the header :
89 * \ it's up to the user doing it !
90 * @param fileName file to be written to
93 bool gdcmDicomDir::Write(std::string fileName)
97 fp1=fopen(fileName.c_str(),"wb");
100 printf("Failed to open(write) File [%s] \n",fileName.c_str());
105 filePreamble=(char*)calloc(128,1);
106 fwrite(filePreamble,128,1,fp1);
107 fwrite("DICM",4,1,fp1);
110 WriteEntries(fp1,DICOMDIR);
117 //-----------------------------------------------------------------------------
120 * \ingroup gdcmDicomDir
124 void gdcmDicomDir::NewDicomDir(std::string path)
126 gdcmDirList fileList(path,1);
132 for(gdcmDirList::iterator it=fileList.begin();
133 it!=fileList.end(); ++it)
135 // std::cout<<*it<<std::endl;
136 header=new gdcmHeader(it->c_str());
137 if(header->IsReadable())
138 list.push_back(header);
143 SetElements(path,list);
146 //-----------------------------------------------------------------------------
149 * \ingroup gdcmDicomDir
153 void gdcmDicomDir::CreateDicomDir()
155 // The list is parsed. When a tag is found :
156 // 1 - we save the beginning iterator
157 // 2 - we continue to parse
158 // 3 - we find an other tag
159 // + we create the object for the precedent tag
162 gdcmDicomDirType type=gdcmDicomDir::GDCM_NONE;
163 ListTag::iterator begin;
164 ListTag::iterator end;
166 begin=listEntries.begin();
168 for(ListTag::iterator i=listEntries.begin();i !=listEntries.end();++i)
170 // std::cout << std::hex <<(*i)->GetGroup() <<
171 // " " <<(*i)->GetElement() << endl;
173 std::string v=(*i)->GetValue();
176 // std::cout<<"PATIENT"<<std::endl;
178 AddObjectToEnd(type,begin,end);
180 type=gdcmDicomDir::GDCM_PATIENT;
186 // std::cout<<"STUDY"<<std::endl;
188 AddObjectToEnd(type,begin,end);
190 type=gdcmDicomDir::GDCM_STUDY;
196 // std::cout<<"SERIES"<<std::endl;
198 AddObjectToEnd(type,begin,end);
200 type=gdcmDicomDir::GDCM_SERIE;
206 // std::cout<<"IMAGE"<<std::endl;
208 AddObjectToEnd(type,begin,end);
210 type=gdcmDicomDir::GDCM_IMAGE;
215 end=GetListEntry().end();
216 AddObjectToEnd(type,begin,end);
219 * \ingroup gdcmDicomDir
223 void gdcmDicomDir::AddObjectToEnd(gdcmDicomDirType type,ListTag::iterator begin,ListTag::iterator end)
230 case gdcmDicomDir::GDCM_PATIENT:
231 AddPatientToEnd(begin,end);
233 case gdcmDicomDir::GDCM_STUDY:
234 AddStudyToEnd(begin,end);
236 case gdcmDicomDir::GDCM_SERIE:
237 AddSerieToEnd(begin,end);
239 case gdcmDicomDir::GDCM_IMAGE:
240 AddImageToEnd(begin,end);
246 * \ingroup gdcmDicomDir
250 void gdcmDicomDir::AddPatientToEnd(ListTag::iterator begin,ListTag::iterator end)
252 patients.push_back(new gdcmPatient(begin,end));
256 * \ingroup gdcmDicomDir
260 void gdcmDicomDir::AddStudyToEnd(ListTag::iterator begin,ListTag::iterator end)
262 if(patients.size()>0)
264 ListPatient::iterator itp=patients.end();
266 (*itp)->AddStudy(new gdcmStudy(begin,end));
270 * \ingroup gdcmDicomDir
274 void gdcmDicomDir::AddSerieToEnd(ListTag::iterator begin,ListTag::iterator end)
276 if(patients.size()>0)
278 ListPatient::iterator itp=patients.end();
281 if((*itp)->GetStudies().size()>0)
283 ListStudy::iterator itst=(*itp)->GetStudies().end();
285 (*itst)->AddSerie(new gdcmSerie(begin,end));
291 * \ingroup gdcmDicomDir
295 void gdcmDicomDir::AddImageToEnd(ListTag::iterator begin,ListTag::iterator end)
297 if(patients.size()>0)
299 ListPatient::iterator itp=patients.end();
302 if((*itp)->GetStudies().size()>0)
304 ListStudy::iterator itst=(*itp)->GetStudies().end();
307 if((*itst)->GetSeries().size()>0)
309 ListSerie::iterator its=(*itst)->GetSeries().end();
311 (*its)->AddImage(new gdcmImage(begin,end));
318 * \ingroup gdcmDicomDir
322 void gdcmDicomDir::SetElements(std::string &path,ListHeader &list)
324 std::string patPrevName="", patPrevID="";
325 std::string studPrevInstanceUID="", studPrevID="";
326 std::string serPrevInstanceUID="", serPrevID="";
328 std::string patCurName, patCurID;
329 std::string studCurInstanceUID, studCurID;
330 std::string serCurInstanceUID, serCurID;
332 SetElement(path,GDCM_NONE,NULL);
334 ListTag::iterator debPat=listEntries.begin();
335 for(ListHeader::iterator it=list.begin();it!=list.end();++it)
337 // get the current file characteristics
338 patCurName=(*it)->GetEntryByNumber(0x0010,0x0010);
339 patCurID=(*it)->GetEntryByNumber(0x0010,0x0011);
340 studCurInstanceUID=(*it)->GetEntryByNumber(0x0020,0x000d);
341 studCurID=(*it)->GetEntryByNumber(0x0020,0x0010);
342 serCurInstanceUID=(*it)->GetEntryByNumber(0x0020,0x000e);
343 serCurID=(*it)->GetEntryByNumber(0x0020,0x0011);
345 if(patCurName!=patPrevName || patCurID!=patPrevID)
346 SetElement(path,GDCM_PATIENT,*it);
348 // if new Study Deal with 'STUDY' Elements
349 if(studCurInstanceUID!=studPrevInstanceUID || studCurID!=studPrevID)
350 SetElement(path,GDCM_STUDY,*it);
352 // if new Serie Deal with 'SERIE' Elements
353 if(serCurInstanceUID!=serPrevInstanceUID || serCurID!=serPrevID)
355 SetElement(path,GDCM_SERIE,*it);
358 // Always Deal with 'IMAGE' Elements
359 SetElement(path,GDCM_IMAGE,*it);
361 patPrevName=patCurName;
363 studPrevInstanceUID=studCurInstanceUID;
364 studPrevID=studCurID;
365 serPrevInstanceUID=serCurInstanceUID;
371 * \ingroup gdcmDicomDir
375 void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader *header)
377 std::list<gdcmElement> elemList;
378 std::list<gdcmElement>::iterator it;
379 guint16 tmpGr, tmpEl;
380 gdcmDictEntry *dictEntry;
381 gdcmHeaderEntry *entry;
387 elemList=gdcmGlobal::GetDicomDirElements()->GetPatientElements();
390 elemList=gdcmGlobal::GetDicomDirElements()->GetStudyElements();
393 elemList=gdcmGlobal::GetDicomDirElements()->GetSerieElements();
396 elemList=gdcmGlobal::GetDicomDirElements()->GetImageElements();
399 elemList=gdcmGlobal::GetDicomDirElements()->GetMetaElements();
405 for(it=elemList.begin();it!=elemList.end();++it)
410 dictEntry=GetPubDict()->GetDictEntryByNumber(tmpGr,tmpEl);
411 entry=new gdcmHeaderEntry(dictEntry);
412 entry->SetOffset(0); // just to avoid missprinting
415 val=header->GetEntryByNumber(tmpGr,tmpEl);
419 if(val==GDCM_UNFOUND)
421 if((tmpGr==0x0004) &&(tmpEl==0x1130) )
423 // TODO force the *end* File Name(remove path)
426 else if( (tmpGr==0x0004) && (tmpEl==0x1500) ) // Only used for image
428 if(header->GetFileName().substr(0,path.length())!=path)
430 dbg.Verbose(0, "gdcmDicomDir::SetElement : the base path of file name is incorrect");
431 val=header->GetFileName();
434 val=&(header->GetFileName()[path.length()]);
441 entry->SetValue(val);
445 if( (dictEntry->GetVR()=="UL") || (dictEntry->GetVR()=="SL") )
449 else if( (dictEntry->GetVR()=="US") || (dictEntry->GetVR()=="SS") )
453 else if(dictEntry->GetVR()=="SQ")
455 entry->SetLength(0xffffffff);
459 entry->SetLength(entry->GetValue().length());
463 listEntries.push_back(entry);
467 //-----------------------------------------------------------------------------