]> Creatis software - gdcm.git/blob - Example/PrintFile.cxx
PrintFile take into account noshadowseq autoref parameter
[gdcm.git] / Example / PrintFile.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: PrintFile.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/06/29 16:00:13 $
7   Version:   $Revision: 1.42 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 #include "gdcmFile.h"
19 #include "gdcmSeqEntry.h"
20 #include "gdcmSQItem.h"
21 #include "gdcmBinEntry.h"
22
23 #include "gdcmFileHelper.h"
24 #include "gdcmDebug.h"
25
26 #include "gdcmArgMgr.h"
27
28 #include <iostream>
29
30
31 void ShowLutData(gdcm::File *e1);
32
33 void ShowLutData(gdcm::File *e1)
34 {
35      // Nothing is written yet to get LUT Data user friendly
36      // The following is to be moved into a PixelReadConvert method
37      // Let here, waiting for a clever idea on the way to do it.
38   
39       gdcm::SeqEntry *modLutSeq = e1->GetSeqEntry(0x0028,0x3000);
40       if ( modLutSeq !=0 )
41       {
42          gdcm::SQItem *sqi= modLutSeq->GetFirstSQItem();
43          if ( sqi != 0 )
44          {
45             std::string lutDescriptor = sqi->GetEntryValue(0x0028,0x3002);
46            if (   /*lutDescriptor   == GDCM_UNFOUND*/ 0 )
47            {
48               //gdcmWarningMacro( "LUT Descriptor is missing" );
49               std::cout << "LUT Descriptor is missing" << std::endl;
50               return;
51             }
52             int length;   // LUT length in Bytes
53             int deb;      // Subscript of the first Lut Value
54             int nbits;    // Lut item size (in Bits)
55
56             int nbRead;    // nb of items in LUT descriptor (must be = 3)
57
58             nbRead = sscanf( lutDescriptor.c_str(),
59                               "%d\\%d\\%d",
60                                &length, &deb, &nbits );
61            std::cout << "length " << length 
62                      << " deb " << deb 
63                      << " nbits " << nbits
64                      << std::endl;
65             if ( nbRead != 3 )
66             {
67                 //gdcmWarningMacro( "Wrong LUT descriptor" );
68                 std::cout << "Wrong LUT descriptor" << std::endl;
69             }
70             //LUT Data (CTX dependent)    
71             gdcm::BinEntry *b = sqi->GetBinEntry(0x0028,0x3006); 
72             if ( b != 0 )
73             { 
74                int BitsAllocated = e1->GetBitsAllocated();
75                if ( BitsAllocated <= 8 )
76                { 
77                   int mult;
78                   if ( ( nbits == 16 ) && ( BitsAllocated == 8 ) )
79                   {
80                   // when LUT item size is different than pixel size
81                      mult = 2; // high byte must be = low byte
82                   }
83                   else
84                   {
85                   // See PS 3.3-2003 C.11.1.1.2 p 619
86                      mult = 1;
87                   }
88                   uint8_t *lut = b->GetBinArea();
89                   for( int i=0; i < length; ++i )
90                   {
91                      std::cout << i+deb << " : \t"
92                                << (int) (lut[i*mult + 1]) << std::endl;
93                   }
94                }
95                else
96                {
97                   uint16_t *lut = (uint16_t *)(b->GetBinArea());  
98                   for( int i=0; i < length; ++i )
99                   {
100                      std::cout << i+deb << " : \t"
101                                << (int) (((uint16_t *)lut)[i])
102                                << std::endl;
103                   }             
104                }
105             }  
106             else
107                std::cout << "No LUT Data BinEntry (0x0028,0x3006) found?!? " 
108                          << std::endl;
109          }
110          else
111             std::cout << "No First SQ Item within (0x0028,0x3000) ?!? " 
112                       << std::endl;      
113       }
114       else
115          std::cout << "No LUT Data SeqEntry (0x0028,0x3000) found " 
116                    << std::endl;
117
118    }
119
120 int main(int argc, char *argv[])
121 {
122
123    START_USAGE(usage)
124    " \n PrintFile : \n",
125    " Display the header of a ACR-NEMA/PAPYRUS/DICOM File",
126    " usage: PrintFile filein=fileName [level=n] [noshadow] [noseq] [debug] ",
127    "        level = 0,1,2 : depending on the amount of details user wants to see",
128    "        noshadow : user doesn't want to load Private groups (odd number)",
129    "        noseq    : user doesn't want to load Sequences ",
130    "        debug    : user wants to run the program in 'debug mode' ",
131    "        showlut  : user wants to display the Palette Color (as an int array)",
132    FINISH_USAGE
133
134    // Initialize Arguments Manager   
135    gdcm::ArgMgr *am= new gdcm::ArgMgr(argc, argv);
136   
137    if (argc == 1)
138    {
139       am->ArgMgrUsage(usage); // Display 'usage'
140       delete am;
141       return 0;
142    }
143
144    char *fileName = am->ArgMgrWantString("filein",usage);
145
146    int loadMode;
147    if ( am->ArgMgrDefined("noshadowseq") )
148       loadMode = NO_SHADOWSEQ;
149    else if ( am->ArgMgrDefined("noshadow") && am->ArgMgrDefined("noseq") )
150       loadMode = NO_SEQ | NO_SHADOW;  
151    else if ( am->ArgMgrDefined("noshadow") )
152       loadMode = NO_SHADOW;
153    else if ( am->ArgMgrDefined("noseq") )
154       loadMode = NO_SEQ;
155    else
156       loadMode = 0;
157
158    int level = am->ArgMgrGetInt("level", 2);
159
160    if (am->ArgMgrDefined("debug"))
161       gdcm::Debug::DebugOn();
162
163    bool showlut = ( 0 != am->ArgMgrDefined("SHOWLUT") );
164  
165    /* if unused Param we give up */
166    if ( am->ArgMgrPrintUnusedLabels() )
167    { 
168       am->ArgMgrUsage(usage);
169       delete am;
170       return 0;
171    } 
172
173    delete am;  // we don't need Argument Manager any longer
174
175    // ----------- End Arguments Manager ---------
176  
177    // gdcm::File::IsReadable() is no usable here, because we deal with
178    // any kind of gdcm-Parsable *document* 
179    // not only gdcm::File (as opposed to gdcm::DicomDir)
180
181    gdcm::File *e1 = new gdcm::File();
182    e1->SetLoadMode(loadMode);
183
184    bool res = e1->Load( fileName );
185    if ( !res )
186    {
187       delete e1;
188       return 0;
189    }
190
191    gdcm::FileHelper *f1 = new gdcm::FileHelper(e1);
192    f1->SetPrintLevel( level );
193
194    f1->Print();   
195
196    std::cout << "\n\n" << std::endl; 
197
198    std::cout <<std::endl;
199    std::cout <<" dataSize    " << f1->GetImageDataSize()    << std::endl;
200    std::cout <<" dataSizeRaw " << f1->GetImageDataRawSize() << std::endl;
201
202    int nX,nY,nZ,sPP,planarConfig;
203    std::string pixelType;
204    nX=e1->GetXSize();
205    nY=e1->GetYSize();
206    nZ=e1->GetZSize();
207    std::cout << " DIMX=" << nX << " DIMY=" << nY << " DIMZ=" << nZ << std::endl;
208
209    pixelType    = e1->GetPixelType();
210    sPP          = e1->GetSamplesPerPixel();
211    planarConfig = e1->GetPlanarConfiguration();
212    
213    std::cout << " pixelType= ["            << pixelType 
214              << "] SamplesPerPixel= ["     << sPP
215              << "] PlanarConfiguration= [" << planarConfig 
216              << "] "<< std::endl 
217              << " PhotometricInterpretation= [" 
218                                 << e1->GetEntryValue(0x0028,0x0004)
219              << "] "<< std::endl;
220
221    int numberOfScalarComponents=e1->GetNumberOfScalarComponents();
222    std::cout << " NumberOfScalarComponents = " << numberOfScalarComponents 
223              <<std::endl
224              << " LUT = " << (e1->HasLUT() ? "TRUE" : "FALSE")
225              << std::endl;
226
227    if ( e1->GetEntryValue(0x0002,0x0010) == gdcm::GDCM_NOTLOADED ) 
228    {
229       std::cout << "Transfer Syntax not loaded. " << std::endl
230                 << "Better you increase MAX_SIZE_LOAD_ELEMENT_VALUE"
231                 << std::endl;
232       return 0;
233    }
234   
235    std::string transferSyntaxName = e1->GetTransferSyntaxName();
236    std::cout << " TransferSyntaxName= [" << transferSyntaxName << "]" 
237              << std::endl;
238    std::cout << " SwapCode= " << e1->GetSwapCode() << std::endl;
239  
240    // Display the LUT as an int array (for debugging purpose)
241    if ( e1->HasLUT() && showlut )
242    {
243       uint8_t* lutrgba = f1->GetLutRGBA();
244       if ( lutrgba == 0 )
245       {
246          std::cout << "Lut RGBA (Palette Color) not built " << std::endl;
247  
248         // Nothing is written yet to get LUT Data user friendly
249         // The following is to be moved into a PixelRedaConvert method
250   
251          gdcm::SeqEntry *modLutSeq = e1->GetSeqEntry(0x0028,0x3000);
252          if ( modLutSeq !=0 )
253          {
254             gdcm::SQItem *sqi= modLutSeq->GetFirstSQItem();
255             if ( !sqi )
256             {
257                std::string lutDescriptor = sqi->GetEntryValue(0x0028,0x3002);
258                int length;   // LUT length in Bytes
259                int deb;      // Subscript of the first Lut Value
260                int nbits;    // Lut item size (in Bits)
261                int nbRead;    // nb of items in LUT descriptor (must be = 3)
262
263                nbRead = sscanf( lutDescriptor.c_str(),
264                                  "%d\\%d\\%d",
265                                   &length, &deb, &nbits );
266                if ( nbRead != 3 )
267                {
268                    //gdcmWarningMacro( "Wrong LUT descriptor" );
269                    std::cout << "Wrong LUT descriptor" << std::endl;
270                }                                                  
271                gdcm::BinEntry *b = sqi->GetBinEntry(0x0028,0x3006);
272                if ( b != 0 )
273                {
274                   if ( b->GetLength() != 0 )
275                   {
276                      std::cout << "---------------------------------------"
277                                << " We should never reach this point      "
278                                << std::endl;
279                      //LoadEntryBinArea(b);    //LUT Data (CTX dependent)
280                   }   
281               }
282            }      
283          }
284          else
285              std::cout << "No LUT Data (0x0028,0x3000) found " << std::endl;
286      }
287       else
288       {
289          if ( f1->GetLutItemSize() == 8 )
290          {
291             for (int i=0;i<f1->GetLutItemNumber();i++)
292                std::cout << i << " : \t"
293                          << (int)(lutrgba[i*4])   << " "
294                          << (int)(lutrgba[i*4+1]) << " "
295                          << (int)(lutrgba[i*4+2]) << std::endl;
296          }
297          else // LutItemSize assumed to be = 16
298          {
299             uint16_t* lutrgba16 = (uint16_t*)lutrgba;
300             for (int i=0;i<f1->GetLutItemNumber();i++)
301                std::cout << i << " : \t"
302                          << (int)(lutrgba16[i*4])   << " "
303                          << (int)(lutrgba16[i*4+1]) << " "
304                          << (int)(lutrgba16[i*4+2]) << std::endl;
305          }
306       }
307    }
308    else if (showlut)
309    {
310       std::cout << "Try LUT Data "<< std::endl;
311       ShowLutData(e1);
312    }
313      
314    if (e1->IsReadable())
315       std::cout <<std::endl<<fileName<<" is Readable"<<std::endl;
316    else
317       std::cout <<std::endl<<fileName<<" is NOT Readable"<<std::endl;
318    std::cout<<std::flush;
319    delete e1;
320    delete f1;
321    return 0;   
322 }