]> Creatis software - gdcm.git/blob - Example/PrintFile.cxx
Warn user when something wrong happens
[gdcm.git] / Example / PrintFile.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: PrintFile.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/07/20 13:39:51 $
7   Version:   $Revision: 1.46 $
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 *f);
32
33 void ShowLutData(gdcm::File *f)
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 = f->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 = f->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] [noshadowseq][noshadow][noseq][debug] ",
127    "        level = 0,1,2 : depending on the amount of details user wants to see",
128    "        noshadowseq: user doesn't want to load Private Sequences",
129    "        noshadow   : user doesn't want to load Private groups (odd number)",
130    "        noseq      : user doesn't want to load Sequences ",
131    "        debug      : user wants to run the program in 'debug mode' ",
132    "        showlut :user wants to display the Palette Color (as an int array)",
133    FINISH_USAGE
134
135    // Initialize Arguments Manager   
136    gdcm::ArgMgr *am= new gdcm::ArgMgr(argc, argv);
137   
138    if (argc == 1 || am->ArgMgrDefined("usage") )
139    {
140       am->ArgMgrUsage(usage); // Display 'usage'
141       delete am;
142       return 0;
143    }
144
145    char *fileName = am->ArgMgrWantString("filein",usage);
146
147    int loadMode = 0x00000000;
148    if ( am->ArgMgrDefined("noshadowseq") )
149       loadMode |= NO_SHADOWSEQ;
150    else 
151    {
152    if ( am->ArgMgrDefined("noshadow") )
153          loadMode |= NO_SHADOW;
154       if ( am->ArgMgrDefined("noseq") )
155          loadMode |= NO_SEQ;
156    }
157
158    int level = am->ArgMgrGetInt("level", 2);
159
160    bool showlut = ( 0 != am->ArgMgrDefined("SHOWLUT") );
161
162    if (am->ArgMgrDefined("debug"))
163       gdcm::Debug::DebugOn();
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 *f = new gdcm::File();
182    f->SetLoadMode(loadMode);
183    f->SetFileName( fileName );
184    bool res = f->Load();
185
186    if ( !res )
187    {
188       std::cout << "Cannot process file [" << fileName << "]" << std::endl;
189       std::cout << "Either it doesn't exist, or it's read protected " 
190                 << std::endl;
191       std::cout << "or it's not a Dicom File, or its 'header' is bugged" 
192                 << std::endl;
193       std::cout << "use 'PrintFile filein=... debug' to try to guess the pb"
194                 << std::endl;
195       delete f;
196       return 0;
197    }
198
199    gdcm::FileHelper *fh = new gdcm::FileHelper(f);
200    fh->SetPrintLevel( level );
201
202    fh->Print();   
203
204    std::cout << "\n\n" << std::endl; 
205
206    std::cout <<std::endl;
207    std::cout <<" dataSize    " << fh->GetImageDataSize()    << std::endl;
208    std::cout <<" dataSizeRaw " << fh->GetImageDataRawSize() << std::endl;
209
210    int nX,nY,nZ,sPP,planarConfig;
211    std::string pixelType;
212    nX=f->GetXSize();
213    nY=f->GetYSize();
214    nZ=f->GetZSize();
215    std::cout << " DIMX=" << nX << " DIMY=" << nY << " DIMZ=" << nZ << std::endl;
216
217    pixelType    = f->GetPixelType();
218    sPP          = f->GetSamplesPerPixel();
219    planarConfig = f->GetPlanarConfiguration();
220    
221    std::cout << " pixelType= ["            << pixelType 
222              << "] SamplesPerPixel= ["     << sPP
223              << "] PlanarConfiguration= [" << planarConfig 
224              << "] "<< std::endl 
225              << " PhotometricInterpretation= [" 
226                                 << f->GetEntryValue(0x0028,0x0004)
227              << "] "<< std::endl;
228
229    int numberOfScalarComponents=f->GetNumberOfScalarComponents();
230    std::cout << " NumberOfScalarComponents = " << numberOfScalarComponents 
231              <<std::endl
232              << " LUT = " << (f->HasLUT() ? "TRUE" : "FALSE")
233              << std::endl;
234
235    if ( f->GetEntryValue(0x0002,0x0010) == gdcm::GDCM_NOTLOADED ) 
236    {
237       std::cout << "Transfer Syntax not loaded. " << std::endl
238                 << "Better you increase MAX_SIZE_LOAD_ELEMENT_VALUE"
239                 << std::endl;
240       return 0;
241    }
242   
243    std::string transferSyntaxName = f->GetTransferSyntaxName();
244    std::cout << " TransferSyntaxName= [" << transferSyntaxName << "]" 
245              << std::endl;
246    std::cout << " SwapCode= " << f->GetSwapCode() << std::endl;
247
248    //std::cout << "\n\n" << std::endl; 
249    //std::cout << "X spacing " << f->GetXSpacing() << std::endl;
250    //std::cout << "Y spacing " << f->GetYSpacing() << std::endl;
251    //std::cout << "Z spacing " << f->GetZSpacing() << std::endl;
252
253    // Display the LUT as an int array (for debugging purpose)
254    if ( f->HasLUT() && showlut )
255    {
256       uint8_t* lutrgba = fh->GetLutRGBA();
257       if ( lutrgba == 0 )
258       {
259          std::cout << "Lut RGBA (Palette Color) not built " << std::endl;
260  
261         // Nothing is written yet to get LUT Data user friendly
262         // The following is to be moved into a PixelRedaConvert method
263   
264          gdcm::SeqEntry *modLutSeq = f->GetSeqEntry(0x0028,0x3000);
265          if ( modLutSeq !=0 )
266          {
267             gdcm::SQItem *sqi= modLutSeq->GetFirstSQItem();
268             if ( !sqi )
269             {
270                std::string lutDescriptor = sqi->GetEntryValue(0x0028,0x3002);
271                int length;   // LUT length in Bytes
272                int deb;      // Subscript of the first Lut Value
273                int nbits;    // Lut item size (in Bits)
274                int nbRead;    // nb of items in LUT descriptor (must be = 3)
275
276                nbRead = sscanf( lutDescriptor.c_str(),
277                                  "%d\\%d\\%d",
278                                   &length, &deb, &nbits );
279                if ( nbRead != 3 )
280                {
281                    //gdcmWarningMacro( "Wrong LUT descriptor" );
282                    std::cout << "Wrong LUT descriptor" << std::endl;
283                }                                                  
284                gdcm::BinEntry *b = sqi->GetBinEntry(0x0028,0x3006);
285                if ( b != 0 )
286                {
287                   if ( b->GetLength() != 0 )
288                   {
289                      std::cout << "---------------------------------------"
290                                << " We should never reach this point      "
291                                << std::endl;
292                      //LoadEntryBinArea(b);    //LUT Data (CTX dependent)
293                   }   
294               }
295            }      
296          }
297          else
298              std::cout << "No LUT Data (0x0028,0x3000) found " << std::endl;
299      }
300       else
301       {
302          if ( fh->GetLutItemSize() == 8 )
303          {
304             for (int i=0;i<fh->GetLutItemNumber();i++)
305                std::cout << i << " : \t"
306                          << (int)(lutrgba[i*4])   << " "
307                          << (int)(lutrgba[i*4+1]) << " "
308                          << (int)(lutrgba[i*4+2]) << std::endl;
309          }
310          else // LutItemSize assumed to be = 16
311          {
312             uint16_t* lutrgba16 = (uint16_t*)lutrgba;
313             for (int i=0;i<fh->GetLutItemNumber();i++)
314                std::cout << i << " : \t"
315                          << (int)(lutrgba16[i*4])   << " "
316                          << (int)(lutrgba16[i*4+1]) << " "
317                          << (int)(lutrgba16[i*4+2]) << std::endl;
318          }
319       }
320    }
321    else if (showlut)
322    {
323       std::cout << "Try LUT Data "<< std::endl;
324       ShowLutData(f);
325    }
326      
327    if (f->IsReadable())
328       std::cout <<std::endl<<fileName<<" is Readable"<<std::endl;
329    else
330       std::cout <<std::endl<<fileName<<" is NOT Readable"<<std::endl;
331    std::cout<<std::flush;
332    delete f;
333    delete fh;
334    return 0;   
335 }