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