]> Creatis software - gdcm.git/blob - Example/ReWriteExtended.cxx
new int(4) vs new int[4] (as usual ?)
[gdcm.git] / Example / ReWriteExtended.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: ReWriteExtended.cxx,v $
5   Language:  C++
6   Date:      $Date: 2007/03/29 12:02:22 $
7   Version:   $Revision: 1.4 $
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 "gdcmFileHelper.h"
20 #include "gdcmDebug.h"
21 #include "gdcmUtil.h"
22 #include "gdcmArgMgr.h"
23
24 #include <iostream>
25
26 int main(int argc, char *argv[])
27 {
28    START_USAGE(usage)
29    " \n ReWriteExtended :\n",
30    " Re write a full gdcm-readable Dicom image using new features           ",
31    "     (DO NOT use right now; checking no achieved !).                    ",
32    "                                                                        ",
33    " usage: ReWriteExtended filein=inputFileName fileout=outputFileName     ",
34    "      filecontent = 1 : USER_OWN_IMAGE                                  ",
35    "                  = 2 : FILTERED_IMAGE                                  ",
36    "                  = 3 : CREATED_IMAGE                                   ",
37    "                  = 4 : UNMODIFIED_PIXELS_IMAGE                         ", 
38    "       [mode=write mode] [noshadow] [noseq][debug]                      ", 
39    "                                                                        ",
40    "        mode = a (ACR), x (Explicit VR Dicom), r (RAW : only pixels)    ",
41    "        noshadowseq: user doesn't want to load Private Sequences        ",
42    "        noshadow : user doesn't want to load Private groups (odd number)",
43    "        noseq    : user doesn't want to load Sequences                  ",
44    "        rgb      : user wants to transform LUT (if any) to RGB pixels   ",
45    "        debug    : developper wants to run the program in 'debug mode'  ",
46    FINISH_USAGE
47
48    // ----- Initialize Arguments Manager ------   
49    gdcm::ArgMgr *am = new gdcm::ArgMgr(argc, argv);
50   
51    if (argc == 1 || am->ArgMgrDefined("usage")) 
52    {
53       am->ArgMgrUsage(usage); // Display 'usage'
54       delete am;
55       return 0;
56    }
57    char *fileName = am->ArgMgrWantString("filein",usage);
58    if ( fileName == NULL )
59    {
60       std::cout << "'filein= ...' is mandatory" << std::endl;
61       delete am;
62       return 0;
63    }
64
65    char *outputFileName = am->ArgMgrWantString("fileout",usage);
66    if ( outputFileName == NULL )
67    {
68       std::cout << "'fileout= ...' is mandatory" << std::endl;
69       delete am;
70       return 0;
71    }
72
73    const char *mode = am->ArgMgrGetString("mode","X");
74    
75    int filecontent =  am->ArgMgrGetInt("filecontent", gdcm::UNMODIFIED_PIXELS_IMAGE);
76    
77    int loadMode = gdcm::LD_ALL;
78    if ( am->ArgMgrDefined("noshadowseq") )
79       loadMode |= gdcm::LD_NOSHADOWSEQ;
80    else 
81    {
82    if ( am->ArgMgrDefined("noshadow") )
83          loadMode |= gdcm::LD_NOSHADOW;
84       if ( am->ArgMgrDefined("noseq") )
85          loadMode |= gdcm::LD_NOSEQ;
86    }
87
88    bool rgb = ( 0 != am->ArgMgrDefined("RGB") );
89
90    if (am->ArgMgrDefined("debug"))
91       gdcm::Debug::DebugOn();
92  
93  
94  
95  
96  // ======================================================================= 
97    bool fail = false;
98       
99    int *boundRoiVal;
100    bool roi = false; 
101    if (am->ArgMgrDefined("roi"))
102    {
103       int nbRoiBound;
104       boundRoiVal = am->ArgMgrGetListOfInt("roi", &nbRoiBound);
105
106       if (nbRoiBound !=4)
107       {
108         std::cout << "Illegal number of 'ROI' boundary values (expected : 4, found:" 
109                   << nbRoiBound << "); 'ROI' ignored" << std::endl;
110         fail = true;
111       }
112       else
113         roi = true;   
114    }
115   
116    int beg = am->ArgMgrGetInt("firstFrame",0);
117    int end = am->ArgMgrGetInt("lastFrame",0);
118  // =======================================================================
119  
120  
121    // if unused Params we give up
122    if ( am->ArgMgrPrintUnusedLabels() )
123    { 
124       am->ArgMgrUsage(usage);
125       delete am;
126       return 0;
127    }
128
129    delete am;  // we don't need Argument Manager any longer
130
131    // ----------- End Arguments Manager ---------
132
133    gdcm::File *f = gdcm::File::New();
134    f->SetLoadMode( loadMode );
135    f->SetFileName( fileName );
136    bool res = f->Load();  
137    if ( !res )
138    {
139       f->Delete();
140       return 0;
141    }
142   
143    if (!f->IsReadable())
144    {
145        std::cerr << "Sorry, not a Readable DICOM / ACR File"  <<std::endl;
146        f->Delete();
147        return 0;
148    }
149
150
151    //std::cout <<std::endl <<" dataSize " << dataSize << std::endl;
152    int nX,nY,nZ,sPP,planarConfig;
153    std::string pixelType, transferSyntaxName;
154    nX=f->GetXSize();
155    nY=f->GetYSize();
156    nZ=f->GetZSize();
157    std::cout << " DIMX=" << nX << " DIMY=" << nY << " DIMZ=" << nZ << std::endl;
158
159    pixelType    = f->GetPixelType();
160    sPP          = f->GetSamplesPerPixel();
161    planarConfig = f->GetPlanarConfiguration();
162    
163    std::cout << " pixelType="           << pixelType 
164              << " SampleserPixel="      << sPP
165              << " PlanarConfiguration=" << planarConfig 
166              << " PhotometricInterpretation=" 
167              << f->GetEntryString(0x0028,0x0004) 
168              << std::endl;
169
170    int numberOfScalarComponents=f->GetNumberOfScalarComponents();
171    std::cout << "NumberOfScalarComponents " << numberOfScalarComponents 
172              <<std::endl;
173    transferSyntaxName = f->GetTransferSyntaxName();
174    std::cout << " TransferSyntaxName= [" << transferSyntaxName << "]" 
175              << std::endl;
176
177
178    
179    gdcm::FileHelper *fh = gdcm::FileHelper::New(f);
180    void *imageData; 
181    int dataSize;
182  
183  
184   // ======================================================================= 
185     int subImDimX = nX;
186     int subImDimY = nY;
187     
188
189     if (roi)
190     {  
191     std::cout << " " << boundRoiVal[0] << " " <<  boundRoiVal[1] << " " << boundRoiVal[2] << " " <<
192      boundRoiVal[3] <<std::endl;
193       if (boundRoiVal[0]<0 || boundRoiVal[0]>=nX)
194       { 
195          std::cout << "xBegin out of bounds; 'roi' ignored" << std::endl;
196          fail = true;      
197       }
198       if (boundRoiVal[1]<0 || boundRoiVal[1]>=nX)
199       { 
200          std::cout << "xEnd out of bounds; 'roi' ignored" << std::endl;
201          fail = true;      
202       }
203       if (boundRoiVal[0] > boundRoiVal[1])
204       { 
205          std::cout << "xBegin greater than xEnd; 'roi' ignored" << std::endl;
206          fail = true;      
207       }
208
209       if (boundRoiVal[2]<0 || boundRoiVal[2]>=nY)
210       { 
211          std::cout << "yBegin out of bounds; 'roi' ignored" << std::endl;
212          fail = true;      
213       }
214       if (boundRoiVal[3]<0 || boundRoiVal[3]>=nY)
215       { 
216          std::cout << "yEnd out of bounds; 'roi' ignored" << std::endl;
217          fail = true;      
218       }
219       if (boundRoiVal[2] > boundRoiVal[3])
220       { 
221          std::cout << "yBegin greater than yEnd; 'roi' ignored" << std::endl;
222          fail = true;      
223       }  
224
225    } 
226    else
227    {
228   
229      boundRoiVal = new int[4];
230      boundRoiVal[0] = 0;
231      boundRoiVal[1] = nX-1;
232      boundRoiVal[2] = 0;
233      boundRoiVal[3] = nY-1;  
234   }
235
236    subImDimX = boundRoiVal[1]-boundRoiVal[0]+1;     
237    subImDimY = boundRoiVal[3]-boundRoiVal[2]+1;  
238     
239    // =======================================================================  
240    if (rgb)
241    {
242       dataSize  = fh->GetImageDataSize();
243       imageData = fh->GetImageData(); // somewhat important... can't remember
244       fh->SetWriteModeToRGB();
245    }
246    else
247    {
248       dataSize  = fh->GetImageDataRawSize();
249       imageData = fh->GetImageDataRaw();// somewhat important... can't remember
250       fh->SetWriteModeToRaw();
251    }
252
253    if ( imageData == 0 ) // to avoid warning
254    {
255       std::cout << "Was unable to read pixels " << std::endl;
256    }
257
258
259    // We trust user. (just an example; *never* trust an user !)  
260    fh->SetContentType((gdcm::ImageContentType)filecontent);
261    
262    /// \todo Here, give the detail of operations a 'decent' user should perform,
263    ///       according to what *he* wants to do.
264
265
266    // an user shouldn't add images to a 'native' serie.
267    // He is allowed to create his own Serie, within a 'native' Study :
268    // if he wants to do so, he has to call gdcm::Util::GetUniqueUID 
269    // only once for a given image set, belonging to a single 'user Serie'
270    
271    std::string SerieInstanceUID;   
272    switch(filecontent)
273    {
274       case gdcm::USER_OWN_IMAGE :
275          SerieInstanceUID = gdcm::Util::CreateUniqueUID();
276          f->SetEntryString(SerieInstanceUID,0x0020,0x000e);
277       break;
278       
279       case gdcm::FILTERED_IMAGE :
280       /// \todo : to be finished!
281       break;      
282
283       case gdcm::CREATED_IMAGE :
284       /// \todo : to be finished!
285       break;
286
287       case gdcm::UNMODIFIED_PIXELS_IMAGE :
288       /// \todo : to be finished!
289       break;      
290    }
291
292    switch (mode[0])
293    {
294       case 'A' :
295       case 'a' :
296       // Writting an ACR file
297       // from a full gdcm readable File
298          std::cout << "WriteACR" << std::endl;
299          fh->WriteAcr(outputFileName);
300          break;
301
302       case 'D' : // Not documented in the 'usage', because the method 
303       case 'd' : //                             is known to be bugged. 
304       // Writting a DICOM Implicit VR file
305       // from a full gdcm readable File
306          std::cout << "WriteDCM Implicit VR" << std::endl;
307          fh->WriteDcmImplVR(outputFileName);
308          break;
309
310       case 'X' :
311       case 'x' :
312       // writting a DICOM Explicit VR 
313       // from a full gdcm readable File
314          std::cout << "WriteDCM Explicit VR" << std::endl;
315          // fh->WriteDcmExplVR(outputFileName);
316          // Try this one :
317          fh->SetWriteTypeToDcmExplVR();
318          fh->Write(outputFileName);
319          break;
320
321       case 'R' :
322       case 'r' :
323       //  Writting a Raw File, 
324          std::cout << "WriteRaw" << std::endl;
325          fh->WriteRawData(outputFileName);
326          break;
327  
328  // Just for fun :
329  // Write a 'Video inverse' version of the file.
330  // *Not* described, on purpose,  in the USAGE  
331       case 'V' :
332       case 'v' :
333          if ( fh->GetFile()->GetBitsAllocated() == 8)
334          {
335             std::cout << "videoinv for 8 bits" << std::endl;
336             for (int i=0; i<dataSize; i++) 
337             {
338                ((uint8_t*)imageData)[i] = 255 - ((uint8_t*)imageData)[i];
339             }
340          }
341          else
342          {
343             std::cout << "videoinv for 16 bits" << std::endl;    
344             for (int i=0; i<dataSize/2; i++) 
345             {
346                ((uint16_t*)imageData)[i] =  65535 - ((uint16_t*)imageData)[i];
347             }
348          }
349          std::cout << "WriteDCM Explicit VR + VideoInv" << std::endl;
350          fh->WriteDcmExplVR(outputFileName);
351          break;
352    }
353
354    f->Delete();
355    fh->Delete();
356    return 0;
357 }
358