]> Creatis software - gdcm.git/blob - Example/exPresentationState.cxx
343deac8593837bd37b6ca6fe2b3328cfdbbc0bb
[gdcm.git] / Example / exPresentationState.cxx
1  
2  /*=========================================================================
3                                                                                 
4   Program:   gdcm
5   Module:    $RCSfile: exPresentationState.cxx,v $
6   Language:  C++
7   Date:      $Date: 2009/05/20 09:45:30 $
8   Version:   $Revision: 1.1 $
9                                                                                 
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.
13                                                                                 
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.
17                                                                                 
18 =========================================================================*/
19
20 #include "gdcmFile.h"
21 // ----------
22 //#include "gdcmValEntry.h"
23 #include "gdcmDataEntry.h"
24 // ----------
25 #include "gdcmSeqEntry.h"
26 #include "gdcmSQItem.h"
27 #include "gdcmDocEntrySet.h"
28 #include "gdcmSerieHelper.h"
29 #include "gdcmDirList.h"
30 #include "gdcmUtil.h"
31
32 #include "gdcmArgMgr.h"
33   
34   GDCM_NAME_SPACE::SeqEntry *CheckIfSequenceExists(GDCM_NAME_SPACE::File *fPR,  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 // -------------------------------------------------------------------------------------------------------
41
42 int main(int argc, char *argv[])
43 {
44    START_USAGE(usage)
45    "\n exPresentationState :\n                                                ",
46    "Extracts and displays the Graphic annotation / Text Objet Sequences of gdcm-parsable Dicom file",
47    "                                                                          ",
48    "usage: exPresentationState {filein=inputFileName|dirin=inputDirectoryName}",
49    "                       [ { [noshadowseq] | [noshadow][noseq] } ] [debug]  ",
50    "       filein : Name of the image  file                                   ",
51    "       PRFile :   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'   ",
57    FINISH_USAGE
58
59    // ----- Initialize Arguments Manager ------
60   
61    GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
62   
63    if (am->ArgMgrDefined("usage") || argc == 1) 
64    {
65       am->ArgMgrUsage(usage); // Display 'usage'
66       delete am;
67       return 0;
68    }
69    
70       if (am->ArgMgrDefined("debug"))
71       GDCM_NAME_SPACE::Debug::DebugOn();
72
73    bool verbose = am->ArgMgrDefined("verbose");
74    
75    const char *fileName = am->ArgMgrGetString("filein");
76    const char *PRName   = am->ArgMgrGetString("PRfile");  
77    
78       /* if unused Param we give up */
79    if ( am->ArgMgrPrintUnusedLabels() )
80    {
81       am->ArgMgrUsage(usage);
82       delete am;
83       return 0;
84    }  
85    delete am;  // ------ we don't need Arguments Manager any longer ------
86
87 // ============================================================
88 //   Read the input image.
89 // ============================================================ 
90
91    GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New( );
92
93 /*
94    //f->SetLoadMode(GDCM_NAME_SPACE::LD_NOSEQ | GDCM_NAME_SPACE::LD_NOSHADOW);
95    f->SetFileName( fileName );
96    f->SetMaxSizeLoadEntry(0xffff);
97    bool res = f->Load();  
98
99    if( GDCM_NAME_SPACE::Debug::GetDebugFlag())
100    {
101       std::cout << "---------------------------------------------" << std::endl;
102       f->Print();
103       std::cout << "---------------------------------------------" << std::endl;
104    }
105    if (!res) {
106        std::cerr << "Sorry, " << fileName << " not a gdcm-readable "
107            << "DICOM / ACR File"
108            << std::endl;
109       f->Delete();
110       return 1;
111    }
112    std::cout << " ... is readable " << std::endl;
113 */
114
115 // =================================================================================
116
117    GDCM_NAME_SPACE::File *fPR = GDCM_NAME_SPACE::File::New( );
118    fPR->SetFileName( PRName );
119    fPR->SetMaxSizeLoadEntry(0xffff);
120    bool res2 = fPR->Load();
121            
122    if (!res2) {
123        std::cout << "Sorry, " << PRName << " not a gdcm-readable "
124            << "DICOM / ACR File"
125            << std::endl;
126       f->Delete();
127       return 1;
128    }
129    std::cout << " ... is readable " << std::endl;
130    
131    GDCM_NAME_SPACE::SeqEntry *se;
132    
133
134    se = CheckIfSequenceExists( fPR, 0x0070, 0x0001);
135    //displaySeekResult(se, 0x0070, 0x0001);
136    if (!se)
137    {
138          std::cout << "Hopeless : " << std::hex <<  0x0070 << "|" << 0x0001 << std::dec << " doesn't exist..." <<std::endl;
139          exit (0);      
140    }
141        
142    std::cout << "[" << PRName << "] is a gdcm-readable PresentationState file, that holds one or more 'ROI'\n" <<std::endl; 
143
144    GDCM_NAME_SPACE::SQItem* currentItem = se->GetFirstSQItem(); // Get the first 'ROI'
145    int i =0;
146    while (currentItem != NULL)
147    {
148         std::cout << "======== Deal With 'ROI' n." << i << std::endl;
149
150         // do what you want with the current 'ROI'
151          dealWithTopLevelItem(currentItem);
152         //...
153
154         currentItem = se->GetNextSQItem(); // Get the next 'ROI'
155         i++;
156    }
157    
158  /*         
159   bool res3 = TestPresentationState(f, fPR);
160   
161   if (res3)
162   {
163      std::cout << "[" << PRName << "] is a gdcm-readable PresentationState file" <<std::endl; 
164   }
165   else
166   {
167      std::cout << "Sorry, [" << PRName << "] is not a gdcm-readable PresentationState file" <<std::endl; 
168   }
169 */
170    
171    
172    f->Delete();
173    fPR->Delete();
174 return 0;
175 }
176
177 //----------------------------------------------------------------------------------------------------
178  
179 bool dealWithTopLevelItem(GDCM_NAME_SPACE::SQItem* currentItem)
180 {
181
182    int tabElement[] = {         0x0008, 0x0009, 0x005a, 0x0060, 0x0086, 
183                         0x0308, 0x0309, 0x030A, 0x030d, 0x0311, 0x0314, 
184                         0x0318, 0x031c, 0x031e, 0x0402, 0x0404, 0x0000 };
185
186    bool res = false;
187    GDCM_NAME_SPACE::SeqEntry *se;
188    
189    se = CheckIfSequenceExists(currentItem, 0x0008, 0x1140);
190    displaySeekResult(se, 0x0008, 0x1140); 
191    if (se != 0)
192    {
193       res = true;
194       dealWithSequence(se);
195    }
196       
197    for(int i=0; tabElement[i]!=0x0000; i++)
198    {
199       se = CheckIfSequenceExists(currentItem, 0x0070, tabElement[i]);
200       displaySeekResult(se, 0x0070, tabElement[i]);       
201       if (se != 0)
202       {
203          res = true;
204          dealWithSequence(se);
205       }
206    } 
207    return (res);
208 }
209
210
211 //----------------------------------------------------------------------------------------------------
212  
213 bool dealWithEndLevelItem(GDCM_NAME_SPACE::SQItem* currentItem)
214 {
215
216    int tabElement[] = {         0x0008, 0x0009, 0x005a, 0x0060, 0x0086, 
217                         0x0308, 0x0309, 0x030A, 0x030d, 0x0311, 0x0314, 
218                         0x0318, 0x031c, 0x031e, 0x0402, 0x0404, 0x0000 };
219
220    bool res = false;
221    GDCM_NAME_SPACE::SeqEntry *se;
222    
223    se = CheckIfSequenceExists(currentItem, 0x0008, 0x1140);
224    displaySeekResult(se, 0x0008, 0x1140); 
225    if (se != 0)
226    {
227       res = true;
228       dealWithSequence(se);
229    }
230       
231    for(int i=0; tabElement[i]!=0x0000; i++)
232    {
233       se = CheckIfSequenceExists(currentItem, 0x0070, tabElement[i]);
234       displaySeekResult(se, 0x0070, tabElement[i]);       
235       if (se != 0)
236       {
237          res = true;
238          dealWithSequence(se);
239       }
240    } 
241    return (res);
242 }
243 //----------------------------------------------------------------------------------------------------
244
245 void dealWithSequence(GDCM_NAME_SPACE::SeqEntry* se)
246 {    
247    uint16_t g = se->GetGroup();
248    uint16_t e = se->GetElement();
249    std::cout << std::hex << "\n------------------------ deal with " << g <<"|" << e <<  std::dec 
250              << "  " << se->GetName() << std::endl;
251      
252    GDCM_NAME_SPACE::SQItem *si = se->GetFirstSQItem();
253    if (!si) {
254       std::cout << "Sequence " << std::hex << g <<"|" << e <<  std::dec <<  "has no Item ?!?" << std::endl;
255       return;
256    }
257    
258    if (g == 0x0008) {
259
260       si->Print(std::cout);
261    } else if (g == 0x0070) {
262    
263       si->Print(std::cout);   
264    } else {
265       std::cout << "Unexpected Group " << std::hex << g << std::hex << std::endl;
266    }
267    
268    si =  se->GetNextSQItem();
269    if (si)
270    {
271       std::cout << "Sequence " << std::hex << g <<"|" << e <<  std::dec <<  "should have only ONE Item ?!?" << std::endl;
272       si->Print(std::cout);
273       return;
274    }
275 }
276
277 //----------------------------------------------------------------------------------------------------
278
279 void displaySeekResult(GDCM_NAME_SPACE::SeqEntry* se, uint16_t g, uint16_t e)
280 {  
281       if (se)
282       {
283         // std::cout << std::hex <<  g << "|" << e << std::dec << " [" << se->GetName() << "] exists" <<std::endl;
284       }
285       else
286       {
287          std::cout << " No " << std::hex <<  g << "|" << e << std::dec << " found" <<std::endl;
288       }
289 }
290       
291 //----------------------------------------------------------------------------------------------------  
292
293 bool TestPresentationState(GDCM_NAME_SPACE::File *f, GDCM_NAME_SPACE::File *fPR)
294 {
295
296 /*------------------------------------------------------
297
298 0070 0001 SQ 1 Graphic Annotation Sequence
299 0070 0008 SQ 1 Text Object Sequence
300 0070 0009 SQ 1 Graphic Object Sequence
301 0070 005a SQ 1 Displayed Area Selection Sequence
302 0070 0060 SQ 1 Graphic Layer Sequence
303 0070 0086 SQ 1 Content Creator's Identification Code Sequence
304 0070 0308 SQ 1 Registration Sequence
305 0070 0309 SQ 1 Matrix Registration Sequence
306 0070 030a SQ 1 Matrix Sequence
307 0070 030d SQ 1 Registration Type Code Sequence
308 0070 0311 SQ 1 Fiducial Identifier Code Sequence
309 0070 0314 SQ 1 Used Fiducials Sequence
310 0070 0318 SQ 1 Graphic Coordinates Data Sequence
311 0070 031c SQ 1 Fiducial Set Sequence
312 0070 031e SQ 1 Fiducial Sequence
313 0070 0402 SQ 1 Blending Sequence
314 0070 0404 SQ 1 Referenced Spatial Registration Sequence
315 ------------------------------------------------------- */
316
317 /*------------------------------------------------------
318 Relevant part of Dicom V3 Dict
319
320 0070 0000 UL 1 Group Length
321 0070 0001 SQ 1 Graphic Annotation Sequence
322 0070 0002 CS 1 Graphic Layer
323 0070 0003 CS 1 Bounding Box Annotation Units
324 0070 0004 CS 1 Anchor Point Annotation Units
325 0070 0005 CS 1 Graphic Annotation Units
326 0070 0006 ST 1 Unformatted Text Value
327 0070 0008 SQ 1 Text Object Sequence
328 0070 0009 SQ 1 Graphic Object Sequence
329 0070 0010 FL 2 Bounding Box Top Left Hand Corner
330 0070 0011 FL 2 Bounding Box Bottom Right Hand Corner
331 0070 0012 CS 1 Bounding Box Text Horizontal Justification
332 0070 0014 FL 2 Anchor Point
333 0070 0015 CS 1 Anchor Point Visibility
334 0070 0020 US 1 Graphic Dimensions
335 0070 0021 US 1 Number of Graphic Points
336 0070 0022 FL 2-2n Graphic Data
337 0070 0023 CS 1 Graphic Type
338 0070 0024 CS 1 Graphic Filled
339 0070 0041 CS 1 Image Horizontal Flip
340 0070 0042 US 1 Image Rotation
341 0070 0052 SL 2 Displayed Area Top Left Hand Corner
342 0070 0053 SL 2 Displayed Area Bottom Right Hand Corner
343 0070 005a SQ 1 Displayed Area Selection Sequence
344 0070 0060 SQ 1 Graphic Layer Sequence
345 0070 0062 IS 1 Graphic Layer Order
346 0070 0066 US 1 Graphic Layer Recommended Display Grayscale Value
347 0070 0067 US 3 Graphic Layer Recommended Display RGB Value (RET)
348 0070 0068 LO 1 Graphic Layer Description
349 0070 0080 CS 1 Content Label
350 0070 0081 LO 1 Content Description
351 0070 0082 DA 1 Presentation Creation Date
352 0070 0083 TM 1 Presentation Creation Time
353 0070 0084 PN 1 Content Creator's Name
354 0070 0086 SQ 1 Content Creator's Identification Code Sequence
355 0070 0100 CS 1 Presentation Size Mode
356 0070 0101 DS 2 Presentation Pixel Spacing
357 0070 0102 IS 2 Presentation Pixel Aspect Ratio
358 0070 0103 FL 1 Presentation Pixel Magnification Ratio
359 0070 0306 CS 1 Shape Type
360 0070 0308 SQ 1 Registration Sequence
361 0070 0309 SQ 1 Matrix Registration Sequence
362 0070 030a SQ 1 Matrix Sequence
363 0070 030c CS 1 Frame of Reference Transformation Matrix Type
364 0070 030d SQ 1 Registration Type Code Sequence
365 0070 030f ST 1 Fiducial Description
366 0070 0310 SH 1 Fiducial Identifier
367 0070 0311 SQ 1 Fiducial Identifier Code Sequence
368 0070 0312 FD 1 Contour Uncertainty Radius
369 0070 0314 SQ 1 Used Fiducials Sequence
370 0070 0318 SQ 1 Graphic Coordinates Data Sequence
371 0070 031a UI 1 Fiducial UID
372 0070 031c SQ 1 Fiducial Set Sequence
373 0070 031e SQ 1 Fiducial Sequence
374 0070 0401 US 3 Graphic Layer Recommended Display CIELab Value
375 0070 0402 SQ 1 Blending Sequence
376 0070 0403 FL 1 Relative Opacity
377 0070 0404 SQ 1 Referenced Spatial Registration Sequence
378 0070 0405 CS 1 Blending Position
379 ------------------------------------------------------- */
380
381 }
382
383
384 // ----------------------------------------------------------------------------------
385
386
387
388 // ----------------------------------------------------------------------------------
389
390
391 GDCM_NAME_SPACE::SeqEntry *CheckIfSequenceExists( GDCM_NAME_SPACE::File *fPR, uint16_t gr, uint16_t el)
392 {
393    GDCM_NAME_SPACE::SeqEntry *se= fPR->GetSeqEntry(gr, el);
394    return se;     
395 }
396
397 // ----------------------------------------------------------------------------------
398   
399 GDCM_NAME_SPACE::SeqEntry *CheckIfSequenceExists( GDCM_NAME_SPACE::SQItem *si, uint16_t gr, uint16_t el)
400 {
401    GDCM_NAME_SPACE::SeqEntry *se= si->GetSeqEntry(gr, el);
402    return se;     
403 }