2 /*=========================================================================
5 Module: $RCSfile: exPresentationState.cxx,v $
7 Date: $Date: 2009/05/25 14:29:16 $
8 Version: $Revision: 1.2 $
10 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
11 l'Image). All rights reserved. See Doc/License.txt or
12 http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
14 This software is distributed WITHOUT ANY WARRANTY; without even
15 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 PURPOSE. See the above copyright notices for more information.
18 =========================================================================*/
22 //#include "gdcmValEntry.h"
23 #include "gdcmDataEntry.h"
25 #include "gdcmSeqEntry.h"
26 #include "gdcmSQItem.h"
27 #include "gdcmDocEntrySet.h"
28 #include "gdcmSerieHelper.h"
29 #include "gdcmDirList.h"
32 #include "gdcmArgMgr.h"
34 GDCM_NAME_SPACE::SeqEntry *CheckIfSequenceExists(GDCM_NAME_SPACE::File *fPS, uint16_t gr, uint16_t el);
35 GDCM_NAME_SPACE::SeqEntry *CheckIfSequenceExists(GDCM_NAME_SPACE::SQItem *si, uint16_t gr, uint16_t el);
36 bool dealWithTopLevelItem(GDCM_NAME_SPACE::SQItem* currentItem);
37 bool dealWithEndLevelItem(GDCM_NAME_SPACE::SQItem* currentItem);
38 void displaySeekResult(GDCM_NAME_SPACE::SeqEntry* currentItem, uint16_t g, uint16_t e);
39 void dealWithSequence(GDCM_NAME_SPACE::SeqEntry* se);
40 // -------------------------------------------------------------------------------------------------------
42 int main(int argc, char *argv[])
45 "\n exPresentationState :\n ",
46 "Extracts and displays the Graphic annotation / Text Objet Sequences of gdcm-parsable Dicom file",
48 "usage: exPresentationState {filein=inputFileName|dirin=inputDirectoryName}",
49 " [ { [noshadowseq] | [noshadow][noseq] } ] [debug] ",
50 " filein : Name of the image file ",
51 " PSFile : Name of the PresentationState file : ",
52 " noshadowseq: user doesn't want to load Private Sequences ",
53 " noshadow : user doesn't want to load Private groups (odd number) ",
54 " noseq : user doesn't want to load Sequences ",
55 " verbose : developper wants to run the program in 'verbose mode' ",
56 " debug : developper wants to run the program in 'debug mode' ",
59 // ----- Initialize Arguments Manager ------
61 GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
63 if (am->ArgMgrDefined("usage") || argc == 1)
65 am->ArgMgrUsage(usage); // Display 'usage'
70 if (am->ArgMgrDefined("debug"))
71 GDCM_NAME_SPACE::Debug::DebugOn();
73 bool verbose = am->ArgMgrDefined("verbose");
75 const char *fileName = am->ArgMgrGetString("filein");
76 const char *PSName = am->ArgMgrGetString("PSfile");
78 /* if unused Param we give up */
79 if ( am->ArgMgrPrintUnusedLabels() )
81 am->ArgMgrUsage(usage);
85 delete am; // ------ we don't need Arguments Manager any longer ------
87 // ============================================================
88 // Read the input image.
89 // ============================================================
91 GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New( );
94 //f->SetLoadMode(GDCM_NAME_SPACE::LD_NOSEQ | GDCM_NAME_SPACE::LD_NOSHADOW);
95 f->SetFileName( fileName );
96 f->SetMaxSizeLoadEntry(0xffff);
99 if( GDCM_NAME_SPACE::Debug::GetDebugFlag())
101 std::cout << "---------------------------------------------" << std::endl;
103 std::cout << "---------------------------------------------" << std::endl;
106 std::cerr << "Sorry, " << fileName << " not a gdcm-readable "
107 << "DICOM / ACR File"
112 std::cout << " ... is readable " << std::endl;
115 // =================================================================================
117 GDCM_NAME_SPACE::File *fPS = GDCM_NAME_SPACE::File::New( );
118 fPS->SetFileName( PSName );
119 fPS->SetMaxSizeLoadEntry(0xffff);
120 bool res2 = fPS->Load();
123 std::cout << "Sorry, " << PSName << " not a gdcm-readable "
124 << "DICOM / ACR File"
130 GDCM_NAME_SPACE::SeqEntry *se;
132 se = CheckIfSequenceExists( fPS, 0x0070, 0x0001);
133 //displaySeekResult(se, 0x0070, 0x0001);
136 std::cout << "Hopeless : " << std::hex << 0x0070 << "|" << 0x0001 << std::dec << " doesn't exist..." <<std::endl;
140 std::cout << "[" << PSName << "] is a gdcm-readable PresentationState file, "
141 << "that (probabely?) holds one or more 'ROI' within [0070|0001] (Graphic Annotation Sequence)\n" <<std::endl;
143 GDCM_NAME_SPACE::SQItem* currentItem = se->GetFirstSQItem(); // Get the first 'ROI'
145 while (currentItem != NULL)
147 std::cout << "======== Deal With 'ROI' n." << i << std::endl;
149 // do what you want with the current 'ROI'
150 dealWithTopLevelItem(currentItem);
153 currentItem = se->GetNextSQItem(); // Get the next 'ROI'
158 bool res3 = TestPresentationState(f, fPS);
162 std::cout << "[" << PSName << "] is a gdcm-readable PresentationState file" <<std::endl;
166 std::cout << "Sorry, [" << PSName << "] is not a gdcm-readable PresentationState file" <<std::endl;
176 //----------------------------------------------------------------------------------------------------
178 bool dealWithTopLevelItem(GDCM_NAME_SPACE::SQItem* currentItem)
180 // probably this list should be cleaned up.
181 // (I didn't find the exact architecture of Presentation State)
182 int tabElement[] = { 0x0008, 0x0009, 0x005a, 0x0060, 0x0086,
183 0x0308, 0x0309, 0x030A, 0x030d, 0x0311, 0x0314,
184 0x0318, 0x031c, 0x031e, 0x0402, 0x0404, 0x0000 };
187 GDCM_NAME_SPACE::SeqEntry *se;
189 se = CheckIfSequenceExists(currentItem, 0x0008, 0x1140);
190 displaySeekResult(se, 0x0008, 0x1140);
194 dealWithSequence(se);
197 for(int i=0; tabElement[i]!=0x0000; i++)
199 se = CheckIfSequenceExists(currentItem, 0x0070, tabElement[i]);
200 displaySeekResult(se, 0x0070, tabElement[i]);
204 dealWithSequence(se);
211 //----------------------------------------------------------------------------------------------------
213 bool dealWithEndLevelItem(GDCM_NAME_SPACE::SQItem* currentItem)
215 // probably this list should be cleaned up, too.
216 // (I didn't find the exact architecture of Presentation State)
217 int tabElement[] = { 0x0008, 0x0009, 0x005a, 0x0060, 0x0086,
218 0x0308, 0x0309, 0x030A, 0x030d, 0x0311, 0x0314,
219 0x0318, 0x031c, 0x031e, 0x0402, 0x0404, 0x0000 };
222 GDCM_NAME_SPACE::SeqEntry *se;
224 se = CheckIfSequenceExists(currentItem, 0x0008, 0x1140);
225 displaySeekResult(se, 0x0008, 0x1140);
229 dealWithSequence(se);
232 for(int i=0; tabElement[i]!=0x0000; i++)
234 se = CheckIfSequenceExists(currentItem, 0x0070, tabElement[i]);
235 displaySeekResult(se, 0x0070, tabElement[i]);
239 dealWithSequence(se);
244 //----------------------------------------------------------------------------------------------------
246 void dealWithSequence(GDCM_NAME_SPACE::SeqEntry* se)
248 uint16_t g = se->GetGroup();
249 uint16_t e = se->GetElement();
250 std::cout << std::hex << "\n------------------------ deal with " << g <<"|" << e << std::dec
251 << " " << se->GetName() << std::endl;
253 GDCM_NAME_SPACE::SQItem *si = se->GetFirstSQItem();
255 std::cout << "Sequence " << std::hex << g <<"|" << e << std::dec << "has no Item ?!?" << std::endl;
261 si->Print(std::cout);
262 } else if (g == 0x0070) {
264 si->Print(std::cout);
266 std::cout << "Unexpected Group " << std::hex << g << std::hex << std::endl;
269 si = se->GetNextSQItem();
272 std::cout << "Sequence " << std::hex << g <<"|" << e << std::dec << "should have only ONE Item ?!?" << std::endl;
273 si->Print(std::cout);
278 //----------------------------------------------------------------------------------------------------
280 void displaySeekResult(GDCM_NAME_SPACE::SeqEntry* se, uint16_t g, uint16_t e)
284 // std::cout << std::hex << g << "|" << e << std::dec << " [" << se->GetName() << "] exists" <<std::endl;
288 std::cout << " No " << std::hex << g << "|" << e << std::dec << " found" <<std::endl;
292 //----------------------------------------------------------------------------------------------------
294 bool TestPresentationState(GDCM_NAME_SPACE::File *f, GDCM_NAME_SPACE::File *fPS)
297 /*------------------------------------------------------
299 0070 0001 SQ 1 Graphic Annotation Sequence
300 0070 0008 SQ 1 Text Object Sequence
301 0070 0009 SQ 1 Graphic Object Sequence
302 0070 005a SQ 1 Displayed Area Selection Sequence
303 0070 0060 SQ 1 Graphic Layer Sequence
304 0070 0086 SQ 1 Content Creator's Identification Code Sequence
305 0070 0308 SQ 1 Registration Sequence
306 0070 0309 SQ 1 Matrix Registration Sequence
307 0070 030a SQ 1 Matrix Sequence
308 0070 030d SQ 1 Registration Type Code Sequence
309 0070 0311 SQ 1 Fiducial Identifier Code Sequence
310 0070 0314 SQ 1 Used Fiducials Sequence
311 0070 0318 SQ 1 Graphic Coordinates Data Sequence
312 0070 031c SQ 1 Fiducial Set Sequence
313 0070 031e SQ 1 Fiducial Sequence
314 0070 0402 SQ 1 Blending Sequence
315 0070 0404 SQ 1 Referenced Spatial Registration Sequence
316 ------------------------------------------------------- */
318 /*------------------------------------------------------
319 Relevant part of Dicom V3 Dict
321 0070 0000 UL 1 Group Length
322 0070 0001 SQ 1 Graphic Annotation Sequence
323 0070 0002 CS 1 Graphic Layer
324 0070 0003 CS 1 Bounding Box Annotation Units
325 0070 0004 CS 1 Anchor Point Annotation Units
326 0070 0005 CS 1 Graphic Annotation Units
327 0070 0006 ST 1 Unformatted Text Value
328 0070 0008 SQ 1 Text Object Sequence
329 0070 0009 SQ 1 Graphic Object Sequence
330 0070 0010 FL 2 Bounding Box Top Left Hand Corner
331 0070 0011 FL 2 Bounding Box Bottom Right Hand Corner
332 0070 0012 CS 1 Bounding Box Text Horizontal Justification
333 0070 0014 FL 2 Anchor Point
334 0070 0015 CS 1 Anchor Point Visibility
335 0070 0020 US 1 Graphic Dimensions
336 0070 0021 US 1 Number of Graphic Points
337 0070 0022 FL 2-2n Graphic Data
338 0070 0023 CS 1 Graphic Type
339 0070 0024 CS 1 Graphic Filled
340 0070 0041 CS 1 Image Horizontal Flip
341 0070 0042 US 1 Image Rotation
342 0070 0052 SL 2 Displayed Area Top Left Hand Corner
343 0070 0053 SL 2 Displayed Area Bottom Right Hand Corner
344 0070 005a SQ 1 Displayed Area Selection Sequence
345 0070 0060 SQ 1 Graphic Layer Sequence
346 0070 0062 IS 1 Graphic Layer Order
347 0070 0066 US 1 Graphic Layer Recommended Display Grayscale Value
348 0070 0067 US 3 Graphic Layer Recommended Display RGB Value (RET)
349 0070 0068 LO 1 Graphic Layer Description
350 0070 0080 CS 1 Content Label
351 0070 0081 LO 1 Content Description
352 0070 0082 DA 1 Presentation Creation Date
353 0070 0083 TM 1 Presentation Creation Time
354 0070 0084 PN 1 Content Creator's Name
355 0070 0086 SQ 1 Content Creator's Identification Code Sequence
356 0070 0100 CS 1 Presentation Size Mode
357 0070 0101 DS 2 Presentation Pixel Spacing
358 0070 0102 IS 2 Presentation Pixel Aspect Ratio
359 0070 0103 FL 1 Presentation Pixel Magnification Ratio
360 0070 0306 CS 1 Shape Type
361 0070 0308 SQ 1 Registration Sequence
362 0070 0309 SQ 1 Matrix Registration Sequence
363 0070 030a SQ 1 Matrix Sequence
364 0070 030c CS 1 Frame of Reference Transformation Matrix Type
365 0070 030d SQ 1 Registration Type Code Sequence
366 0070 030f ST 1 Fiducial Description
367 0070 0310 SH 1 Fiducial Identifier
368 0070 0311 SQ 1 Fiducial Identifier Code Sequence
369 0070 0312 FD 1 Contour Uncertainty Radius
370 0070 0314 SQ 1 Used Fiducials Sequence
371 0070 0318 SQ 1 Graphic Coordinates Data Sequence
372 0070 031a UI 1 Fiducial UID
373 0070 031c SQ 1 Fiducial Set Sequence
374 0070 031e SQ 1 Fiducial Sequence
375 0070 0401 US 3 Graphic Layer Recommended Display CIELab Value
376 0070 0402 SQ 1 Blending Sequence
377 0070 0403 FL 1 Relative Opacity
378 0070 0404 SQ 1 Referenced Spatial Registration Sequence
379 0070 0405 CS 1 Blending Position
380 ------------------------------------------------------- */
385 // ----------------------------------------------------------------------------------
389 // ----------------------------------------------------------------------------------
392 GDCM_NAME_SPACE::SeqEntry *CheckIfSequenceExists( GDCM_NAME_SPACE::File *fPS, uint16_t gr, uint16_t el)
394 GDCM_NAME_SPACE::SeqEntry *se= fPS->GetSeqEntry(gr, el);
398 // ----------------------------------------------------------------------------------
400 GDCM_NAME_SPACE::SeqEntry *CheckIfSequenceExists( GDCM_NAME_SPACE::SQItem *si, uint16_t gr, uint16_t el)
402 GDCM_NAME_SPACE::SeqEntry *se= si->GetSeqEntry(gr, el);