]> Creatis software - gdcm.git/blob - Example/PrintFile.cxx
Begin of kosherization of Example
[gdcm.git] / Example / PrintFile.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: PrintFile.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/07/07 17:31:53 $
7   Version:   $Revision: 1.45 $
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();        // just to see
185
186    if ( !res )
187    {
188       delete f;
189       return 0;
190    }
191
192    gdcm::FileHelper *fh = new gdcm::FileHelper(f);
193    fh->SetPrintLevel( level );
194
195    fh->Print();   
196
197    std::cout << "\n\n" << std::endl; 
198
199    std::cout <<std::endl;
200    std::cout <<" dataSize    " << fh->GetImageDataSize()    << std::endl;
201    std::cout <<" dataSizeRaw " << fh->GetImageDataRawSize() << std::endl;
202
203    int nX,nY,nZ,sPP,planarConfig;
204    std::string pixelType;
205    nX=f->GetXSize();
206    nY=f->GetYSize();
207    nZ=f->GetZSize();
208    std::cout << " DIMX=" << nX << " DIMY=" << nY << " DIMZ=" << nZ << std::endl;
209
210    pixelType    = f->GetPixelType();
211    sPP          = f->GetSamplesPerPixel();
212    planarConfig = f->GetPlanarConfiguration();
213    
214    std::cout << " pixelType= ["            << pixelType 
215              << "] SamplesPerPixel= ["     << sPP
216              << "] PlanarConfiguration= [" << planarConfig 
217              << "] "<< std::endl 
218              << " PhotometricInterpretation= [" 
219                                 << f->GetEntryValue(0x0028,0x0004)
220              << "] "<< std::endl;
221
222    int numberOfScalarComponents=f->GetNumberOfScalarComponents();
223    std::cout << " NumberOfScalarComponents = " << numberOfScalarComponents 
224              <<std::endl
225              << " LUT = " << (f->HasLUT() ? "TRUE" : "FALSE")
226              << std::endl;
227
228    if ( f->GetEntryValue(0x0002,0x0010) == gdcm::GDCM_NOTLOADED ) 
229    {
230       std::cout << "Transfer Syntax not loaded. " << std::endl
231                 << "Better you increase MAX_SIZE_LOAD_ELEMENT_VALUE"
232                 << std::endl;
233       return 0;
234    }
235   
236    std::string transferSyntaxName = f->GetTransferSyntaxName();
237    std::cout << " TransferSyntaxName= [" << transferSyntaxName << "]" 
238              << std::endl;
239    std::cout << " SwapCode= " << f->GetSwapCode() << std::endl;
240
241    //std::cout << "\n\n" << std::endl; 
242    //std::cout << "X spacing " << f->GetXSpacing() << std::endl;
243    //std::cout << "Y spacing " << f->GetYSpacing() << std::endl;
244    //std::cout << "Z spacing " << f->GetZSpacing() << std::endl;
245
246    // Display the LUT as an int array (for debugging purpose)
247    if ( f->HasLUT() && showlut )
248    {
249       uint8_t* lutrgba = fh->GetLutRGBA();
250       if ( lutrgba == 0 )
251       {
252          std::cout << "Lut RGBA (Palette Color) not built " << std::endl;
253  
254         // Nothing is written yet to get LUT Data user friendly
255         // The following is to be moved into a PixelRedaConvert method
256   
257          gdcm::SeqEntry *modLutSeq = f->GetSeqEntry(0x0028,0x3000);
258          if ( modLutSeq !=0 )
259          {
260             gdcm::SQItem *sqi= modLutSeq->GetFirstSQItem();
261             if ( !sqi )
262             {
263                std::string lutDescriptor = sqi->GetEntryValue(0x0028,0x3002);
264                int length;   // LUT length in Bytes
265                int deb;      // Subscript of the first Lut Value
266                int nbits;    // Lut item size (in Bits)
267                int nbRead;    // nb of items in LUT descriptor (must be = 3)
268
269                nbRead = sscanf( lutDescriptor.c_str(),
270                                  "%d\\%d\\%d",
271                                   &length, &deb, &nbits );
272                if ( nbRead != 3 )
273                {
274                    //gdcmWarningMacro( "Wrong LUT descriptor" );
275                    std::cout << "Wrong LUT descriptor" << std::endl;
276                }                                                  
277                gdcm::BinEntry *b = sqi->GetBinEntry(0x0028,0x3006);
278                if ( b != 0 )
279                {
280                   if ( b->GetLength() != 0 )
281                   {
282                      std::cout << "---------------------------------------"
283                                << " We should never reach this point      "
284                                << std::endl;
285                      //LoadEntryBinArea(b);    //LUT Data (CTX dependent)
286                   }   
287               }
288            }      
289          }
290          else
291              std::cout << "No LUT Data (0x0028,0x3000) found " << std::endl;
292      }
293       else
294       {
295          if ( fh->GetLutItemSize() == 8 )
296          {
297             for (int i=0;i<fh->GetLutItemNumber();i++)
298                std::cout << i << " : \t"
299                          << (int)(lutrgba[i*4])   << " "
300                          << (int)(lutrgba[i*4+1]) << " "
301                          << (int)(lutrgba[i*4+2]) << std::endl;
302          }
303          else // LutItemSize assumed to be = 16
304          {
305             uint16_t* lutrgba16 = (uint16_t*)lutrgba;
306             for (int i=0;i<fh->GetLutItemNumber();i++)
307                std::cout << i << " : \t"
308                          << (int)(lutrgba16[i*4])   << " "
309                          << (int)(lutrgba16[i*4+1]) << " "
310                          << (int)(lutrgba16[i*4+2]) << std::endl;
311          }
312       }
313    }
314    else if (showlut)
315    {
316       std::cout << "Try LUT Data "<< std::endl;
317       ShowLutData(f);
318    }
319      
320    if (f->IsReadable())
321       std::cout <<std::endl<<fileName<<" is Readable"<<std::endl;
322    else
323       std::cout <<std::endl<<fileName<<" is NOT Readable"<<std::endl;
324    std::cout<<std::flush;
325    delete f;
326    delete fh;
327    return 0;   
328 }