/*========================================================================= Program: gdcm Module: $RCSfile: exExplorePresentationState.cxx,v $ Language: C++ Date: $Date: 2010/09/01 14:40:00 $ Version: $Revision: 1.1 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "gdcmFile.h" #include "gdcmArgMgr.h" #include "gdcmSeqEntry.h" #include "gdcmSQItem.h" #include "gdcmDocEntrySet.h" //#include "gdcmSerieHelper.h" #include "gdcmDirList.h" #include "gdcmUtil.h" typedef struct { // 0020|0013 [IS] [Instance Number] std::string referencedInstanceNumber; // 0004|1500 [CS] [Referenced File ID] std::string referencedFileName; } FILEINFO; GDCM_NAME_SPACE::SeqEntry *CheckIfSequenceExists(GDCM_NAME_SPACE::File *fPS, uint16_t gr, uint16_t el); GDCM_NAME_SPACE::SeqEntry *CheckIfSequenceExists(GDCM_NAME_SPACE::SQItem *si, uint16_t gr, uint16_t el); bool dealWithCurrentFile(const char *PSName); bool dealWithTopLevelItem(GDCM_NAME_SPACE::SQItem* currentItem); bool dealWithEndLevelItem(GDCM_NAME_SPACE::SQItem* currentItem); void displaySeekResult(GDCM_NAME_SPACE::SeqEntry* currentItem, uint16_t g, uint16_t e); bool dealWithSequence(GDCM_NAME_SPACE::SeqEntry* se); std::string dealWithReferencedFile(GDCM_NAME_SPACE::SQItem *si); std::map dealWithDicomDir(const char *dicomdirname); bool verbose; bool PSNameAlreadyShown; std::map m; std::string currentPSFileName; int main(int argc, char *argv[]) { START_USAGE(usage) "\n exExplorePresentationState :\n ", FINISH_USAGE // ----- Initialize Arguments Manager ------ GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv); if (am->ArgMgrDefined("usage") || argc == 1) { am->ArgMgrUsage(usage); // Display 'usage' delete am; return 0; } if (am->ArgMgrDefined("debug")) GDCM_NAME_SPACE::Debug::DebugOn(); /*bool */verbose = am->ArgMgrDefined("verbose"); bool rec = ( 0 != am->ArgMgrDefined("rec") ); const char *dirName = am->ArgMgrGetString("dirin"); const char *dicomdirname = am->ArgMgrGetString("dicomdir"); /* if unused Param we give up */ if ( am->ArgMgrPrintUnusedLabels() ) { am->ArgMgrUsage(usage); delete am; return 0; } delete am; // ------ we don't need Arguments Manager any longer ------ // =========================================================================== // ========================= Deal with the relevant DICOMDIR ================= // =========================================================================== /*std::map */ m = dealWithDicomDir(dicomdirname); // =========================================================================== // ========================= Deal with the Directory holding DICOM images == // =========================================================================== std::cout << " Image Directory Name [" << dirName << "]\n\n" << std::endl; GDCM_NAME_SPACE::DirList dirList(dirName,rec); // gets recursively (or not) the file list GDCM_NAME_SPACE::DirListType fileList = dirList.GetFilenames(); GDCM_NAME_SPACE::File *f; bool res; if (fileList.size() == 0) { std::cout << "No file found in : [" << dirName << "]" << std::endl; } for( GDCM_NAME_SPACE::DirListType::iterator it = fileList.begin(); it != fileList.end(); ++it ) { currentPSFileName = it->c_str(); if (verbose) std::cout << std::endl<<" Start processing :[" << it->c_str() << "]" << std::endl; f = GDCM_NAME_SPACE::File::New(); //f->SetLoadMode(loadMode); f->SetFileName( it->c_str() ); res = f->GDCM_NAME_SPACE::Document::Load(); if ( !res ) { if (verbose) { std::cout << "Cannot process file [" << it->c_str() << "]" << std::endl; std::cout << "Either it doesn't exist, or it's read protected " << std::endl; std::cout << "or it's not a Dicom File, or its 'header' is bugged" << std::endl; std::cout << "use 'PrintFile filein=... debug' " << "to try to guess the pb" << std::endl; } f->Delete(); continue; } bool resFile = dealWithCurrentFile(it->c_str()); if (verbose) std::cout << "\n\n" <c_str() << "]==" << resFile << std::endl; //return resFile; continue; } } //---------------------------------------------------------------------------------------------------- bool dealWithCurrentFile(const char *PSName) { GDCM_NAME_SPACE::File *fPS = GDCM_NAME_SPACE::File::New( ); fPS->SetFileName( PSName ); fPS->SetMaxSizeLoadEntry(0xffff); bool res2 = fPS->Load(); if (!res2) { if (verbose) std::cout << "Sorry, " << PSName << " not a gdcm-readable " << "DICOM / ACR File" << std::endl; fPS->Delete(); return false; } GDCM_NAME_SPACE::SeqEntry *se; se = CheckIfSequenceExists( fPS, 0x0070, 0x0001); //displaySeekResult(se, 0x0070, 0x0001); if (!se) { if (verbose) std::cout << "[" << PSName << "] : Hopeless (" << std::hex << 0x0070 << "|" << 0x0001 << std::dec << " doesn't exist...)" <GetFirstSQItem(); // Get the first 'ROI' if (currentItem == NULL) { if (verbose) std::cout << "======== Deal With NOTHING! (Sequence 0070|0001 [Graphic Annotation Sequence] has NO item ?!?) within " << PSName << "]" << std::endl; return false; } int i =0; bool res3; bool finalRes = false; while (currentItem != NULL) { if (verbose) std::cout << "======== Deal With 'ROI' n." << i << std::endl; // do what you want with the current 'ROI' res3 = dealWithTopLevelItem(currentItem); if (res3) finalRes = true; //... currentItem = se->GetNextSQItem(); // Get the next 'ROI' i++; } if (finalRes) std::cout << "=============================(within PS File :[" << PSName << "]\n\n" << std::endl; fPS->Delete(); if(verbose) std::cout << "\n\n" <GetGroup(); uint16_t e = se->GetElement(); if (verbose) std::cout << std::hex << "\n------------------------ deal with " << g <<"|" << e << std::dec << " " << se->GetName() << std::endl; GDCM_NAME_SPACE::SQItem *si = se->GetFirstSQItem(); if (!si) { if (verbose) std::cout << "Sequence " << std::hex << g <<"|" << e << std::dec << "has no Item ?!?" << std::endl; return false; } std::string referencedFileUID; //std::cout << "\n============================== [" << currentPSFileName << "] =================" << std::endl; if (g == 0x0008) { if (verbose) si->Print(std::cout); referencedFileUID = dealWithReferencedFile(si); // std::cout << " referencedFile UID[" << referencedFileUID <<"]" << std::endl; } else if (g == 0x0070) { if (verbose) si->Print(std::cout); } else { if (verbose) std::cout << "Unexpected Group " << std::hex << g << std::hex << std::endl; } si = se->GetNextSQItem(); if (si) { if (verbose) std::cout << "Sequence " << std::hex << g <<"|" << e << std::dec << "should have only ONE Item ?!?" << std::endl; // if (verbose) // si->Print(std::cout); return false; } return true; } //---------------------------------------------------------------------------------------------------- void displaySeekResult(GDCM_NAME_SPACE::SeqEntry* se, uint16_t g, uint16_t e) { if (se) { // std::cout << std::hex << g << "|" << e << std::dec << " [" << se->GetName() << "] exists" <GetSeqEntry(gr, el); return se; } // ---------------------------------------------------------------------------------- GDCM_NAME_SPACE::SeqEntry *CheckIfSequenceExists( GDCM_NAME_SPACE::SQItem *si, uint16_t gr, uint16_t el) { GDCM_NAME_SPACE::SeqEntry *se= si->GetSeqEntry(gr, el); return se; } // ---------------------------------------------------------------------------------- std::string dealWithReferencedFile(GDCM_NAME_SPACE::SQItem *si) { // GDCM_NAME_SPACE::DocEntry *si = GetDocEntry(0x0008, 0x1155); // Look for : 0004|1511 [UI] [Referenced SOP Instance UID in File] std::string referencedFileUID = si->GetEntryString(0x0008, 0x1155); // std::cout << " referencedFile UID[" << referencedFileUID <<"]" << std::endl; if (verbose) std::cout << "m[" << referencedFileUID << "] = "; std::cout << "[" << m[referencedFileUID].referencedInstanceNumber << "] [" << m[referencedFileUID].referencedFileName << "]" << std::endl; return referencedFileUID; } // ---------------------------------------------------------------------------------- std::map dealWithDicomDir(const char *dicomdirname) { FILEINFO fi; GDCM_NAME_SPACE::File *f; bool res; std::map m; std::cout << std::endl<<" Start reading DICOMDIR :[" << dicomdirname << "]" << std::endl; f = GDCM_NAME_SPACE::File::New(); //f->SetLoadMode(loadMode); f->SetFileName( dicomdirname ); // Don't load a DicomDir ! res = f->GDCM_NAME_SPACE::Document::Load(); if ( !res ) { std::cout << "Cannot process file [" << dicomdirname << "]" << std::endl; std::cout << "Either it doesn't exist, or it's read protected " << std::endl; std::cout << "or it's not a Dicom File, or its 'header' is bugged" << std::endl; std::cout << "use 'PrintFile filein=... debug' " << "to try to guess the pb" << std::endl; f->Delete(); /// \TODO : throw an exception return m;; } // Get 0004|1220 [SQ] [Directory Record Sequence] GDCM_NAME_SPACE::SeqEntry *dsr= f->GetSeqEntry(0x0004,0x1220); if (!dsr) { if (verbose) std::cout << "[" << dicomdirname << "] : Hopeless (" << std::hex << 0x0094 << "|" << 0x01220 << std::dec << " -Directory Record Sequence- doesn't exist...)" <Delete(); /// \TODO : throw an exception return m; } GDCM_NAME_SPACE::SQItem* currentItem = dsr->GetFirstSQItem(); // Get the first 'ROI' if (currentItem == NULL) { if (verbose) std::cout << "======== Deal With NOTHING! (Sequence 0004|1220 [Directory Record Sequence] has NO item ?!?)" << std::endl; /// \TODO : throw an exception return m; } int i =0; while (currentItem != NULL) { // Get 0020|0013 [IS] [Instance Number] fi.referencedInstanceNumber = currentItem->GetEntryString(0x0020, 0x0013); // Get 0004|1500 [CS] [Referenced File ID] fi.referencedFileName = currentItem->GetEntryString(0x0004, 0x1500); // Get0004|1511 [UI] [Referenced SOP Instance UID in File] std::string referencedFileSopInstanceUID = currentItem->GetEntryString(0x0004, 0x1511); m[referencedFileSopInstanceUID] = fi; currentItem = dsr->GetNextSQItem(); // Get the next 'ROI' i++; } if (verbose) for(std::map::iterator it = m.begin(); it != m.end(); ++it) { std::cout << "m[" << (*it).first << "] = [" << (*it).second.referencedInstanceNumber << "] [" << (*it).second.referencedFileName << std::endl; } return m; }