]> Creatis software - gdcm.git/blob - Example/PrintFile.cxx
Waiting for a clever idea on the way to userfriendly manage them,
[gdcm.git] / Example / PrintFile.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: PrintFile.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/06/22 08:37:54 $
7   Version:   $Revision: 1.41 $
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("noshadow") && am->ArgMgrDefined("noseq") )
148        loadMode = NO_SEQ | NO_SHADOW;  
149    else if ( am->ArgMgrDefined("noshadow") )
150       loadMode = NO_SHADOW;
151    else if ( am->ArgMgrDefined("noseq") )
152       loadMode = NO_SEQ;
153    else
154       loadMode = 0;
155
156    int level = am->ArgMgrGetInt("level", 2);
157
158    if (am->ArgMgrDefined("debug"))
159       gdcm::Debug::DebugOn();
160
161    bool showlut = ( 0 != am->ArgMgrDefined("SHOWLUT") );
162  
163    /* if unused Param we give up */
164    if ( am->ArgMgrPrintUnusedLabels() )
165    { 
166       am->ArgMgrUsage(usage);
167       delete am;
168       return 0;
169    } 
170
171    delete am;  // we don't need Argument Manager any longer
172
173    // ----------- End Arguments Manager ---------
174  
175    // gdcm::File::IsReadable() is no usable here, because we deal with
176    // any kind of gdcm-Parsable *document* 
177    // not only gdcm::File (as opposed to gdcm::DicomDir)
178
179    gdcm::File *e1 = new gdcm::File();
180    e1->SetLoadMode(loadMode);
181
182    bool res = e1->Load( fileName );
183    if ( !res )
184    {
185       delete e1;
186       return 0;
187    }
188
189    gdcm::FileHelper *f1 = new gdcm::FileHelper(e1);
190    f1->SetPrintLevel( level );
191
192    f1->Print();   
193
194    std::cout << "\n\n" << std::endl; 
195
196    std::cout <<std::endl;
197    std::cout <<" dataSize    " << f1->GetImageDataSize()    << std::endl;
198    std::cout <<" dataSizeRaw " << f1->GetImageDataRawSize() << std::endl;
199
200    int nX,nY,nZ,sPP,planarConfig;
201    std::string pixelType;
202    nX=e1->GetXSize();
203    nY=e1->GetYSize();
204    nZ=e1->GetZSize();
205    std::cout << " DIMX=" << nX << " DIMY=" << nY << " DIMZ=" << nZ << std::endl;
206
207    pixelType    = e1->GetPixelType();
208    sPP          = e1->GetSamplesPerPixel();
209    planarConfig = e1->GetPlanarConfiguration();
210    
211    std::cout << " pixelType= ["            << pixelType 
212              << "] SamplesPerPixel= ["     << sPP
213              << "] PlanarConfiguration= [" << planarConfig 
214              << "] "<< std::endl 
215              << " PhotometricInterpretation= [" 
216                                 << e1->GetEntryValue(0x0028,0x0004)
217              << "] "<< std::endl;
218
219    int numberOfScalarComponents=e1->GetNumberOfScalarComponents();
220    std::cout << " NumberOfScalarComponents = " << numberOfScalarComponents 
221              <<std::endl
222              << " LUT = " << (e1->HasLUT() ? "TRUE" : "FALSE")
223              << std::endl;
224
225    if ( e1->GetEntryValue(0x0002,0x0010) == gdcm::GDCM_NOTLOADED ) 
226    {
227       std::cout << "Transfer Syntax not loaded. " << std::endl
228                 << "Better you increase MAX_SIZE_LOAD_ELEMENT_VALUE"
229                 << std::endl;
230       return 0;
231    }
232   
233    std::string transferSyntaxName = e1->GetTransferSyntaxName();
234    std::cout << " TransferSyntaxName= [" << transferSyntaxName << "]" 
235              << std::endl;
236    std::cout << " SwapCode= " << e1->GetSwapCode() << std::endl;
237  
238    // Display the LUT as an int array (for debugging purpose)
239    if ( e1->HasLUT() && showlut )
240    {
241       uint8_t* lutrgba = f1->GetLutRGBA();
242       if ( lutrgba == 0 )
243       {
244          std::cout << "Lut RGBA (Palette Color) not built " << std::endl;
245  
246         // Nothing is written yet to get LUT Data user friendly
247         // The following is to be moved into a PixelRedaConvert method
248   
249          gdcm::SeqEntry *modLutSeq = e1->GetSeqEntry(0x0028,0x3000);
250          if ( modLutSeq !=0 )
251          {
252             gdcm::SQItem *sqi= modLutSeq->GetFirstSQItem();
253             if ( !sqi )
254             {
255                std::string lutDescriptor = sqi->GetEntryValue(0x0028,0x3002);
256                int length;   // LUT length in Bytes
257                int deb;      // Subscript of the first Lut Value
258                int nbits;    // Lut item size (in Bits)
259                int nbRead;    // nb of items in LUT descriptor (must be = 3)
260
261                nbRead = sscanf( lutDescriptor.c_str(),
262                                  "%d\\%d\\%d",
263                                   &length, &deb, &nbits );
264                if ( nbRead != 3 )
265                {
266                    //gdcmWarningMacro( "Wrong LUT descriptor" );
267                    std::cout << "Wrong LUT descriptor" << std::endl;
268                }                                                  
269                gdcm::BinEntry *b = sqi->GetBinEntry(0x0028,0x3006);
270                if ( b != 0 )
271                {
272                   if ( b->GetLength() != 0 )
273                   {
274                      std::cout << "---------------------------------------"
275                                << " We should never reach this point      "
276                                << std::endl;
277                      //LoadEntryBinArea(b);    //LUT Data (CTX dependent)
278                   }   
279               }
280            }      
281          }
282          else
283              std::cout << "No LUT Data (0x0028,0x3000) found " << std::endl;
284      }
285       else
286       {
287          if ( f1->GetLutItemSize() == 8 )
288          {
289             for (int i=0;i<f1->GetLutItemNumber();i++)
290                std::cout << i << " : \t"
291                          << (int)(lutrgba[i*4])   << " "
292                          << (int)(lutrgba[i*4+1]) << " "
293                          << (int)(lutrgba[i*4+2]) << std::endl;
294          }
295          else // LutItemSize assumed to be = 16
296          {
297             uint16_t* lutrgba16 = (uint16_t*)lutrgba;
298             for (int i=0;i<f1->GetLutItemNumber();i++)
299                std::cout << i << " : \t"
300                          << (int)(lutrgba16[i*4])   << " "
301                          << (int)(lutrgba16[i*4+1]) << " "
302                          << (int)(lutrgba16[i*4+2]) << std::endl;
303          }
304       }
305    }
306    else if (showlut)
307    {
308       std::cout << "Try LUT Data "<< std::endl;
309       ShowLutData(e1);
310    }
311      
312    if (e1->IsReadable())
313       std::cout <<std::endl<<fileName<<" is Readable"<<std::endl;
314    else
315       std::cout <<std::endl<<fileName<<" is NOT Readable"<<std::endl;
316    std::cout<<std::flush;
317    delete e1;
318    delete f1;
319    return 0;   
320 }