]> Creatis software - gdcm.git/blob - Example/RawToDicom.cxx
Add 32 bits support
[gdcm.git] / Example / RawToDicom.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: RawToDicom.cxx,v $
5   Language:  C++
6   Date:      $Date: 2006/07/17 13:27:57 $
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
19 /**
20  * Writes a Dicom file from a Raw File
21  * User has to supply parameters. 
22  * 
23  */
24 #include "gdcmFile.h"
25 #include "gdcmFileHelper.h"
26 #include "gdcmDebug.h"
27 #include "gdcmUtil.h"
28 #include "gdcmArgMgr.h"
29
30 #include <iostream>
31 #include <sstream>
32
33 int main(int argc, char *argv[])
34 {
35    START_USAGE(usage)
36    " \n RawToDicom : \n                                                       ",
37    " Writes a Dicom file from a Raw File                                      ",
38    " usage: RawToDicom filein=inputFileName                                   ",
39    "                   fileout=outputFileName                                 ",
40    "                   rows=nb of Rows                                        ",
41    "                   lines=nb of Lines,                                     ",
42    "                   pixeltype={8U|8S|16U|16S|32U|32S}                      ",
43    "                   [frames = nb of Frames] //defaulted to 1               ",
44    "                   [samples = {1|3}}       //defaulted to 1(1:Gray,3:RGB) ",
45    "                   [patientname = Patient's name]                         ",
46    "                   [debug]                                                ",
47    "                                                                          ",
48    "      debug      : developper wants to run the program in 'debug mode'    ",
49    FINISH_USAGE
50    
51
52    // Initialize Arguments Manager   
53    gdcm::ArgMgr *am= new gdcm::ArgMgr(argc, argv);
54   
55    if (argc == 1 || am->ArgMgrDefined("usage") )
56    {
57       am->ArgMgrUsage(usage); // Display 'usage'
58       delete am;
59       return 1;
60    }
61
62    const char *inputFileName  = am->ArgMgrGetString("filein");
63    const char *outputFileName = am->ArgMgrGetString("fileout");
64    
65    const char *patientName = am->ArgMgrGetString("patientname");
66    
67    int nX = am->ArgMgrWantInt("rows", usage);
68    int nY = am->ArgMgrWantInt("lines", usage);
69    int nZ = am->ArgMgrGetInt("frames", 1);
70    int samplesPerPixel = am->ArgMgrGetInt("samples", 1);
71    
72    
73    char *pixelType = am->ArgMgrWantString("pixeltype", usage);
74    
75    if (am->ArgMgrDefined("debug"))
76       gdcm::Debug::DebugOn();
77
78    /* if unused Param we give up */
79    if ( am->ArgMgrPrintUnusedLabels() )
80    {
81       am->ArgMgrUsage(usage);
82       delete am;
83       return 1;
84    } 
85
86    delete am;  // we don't need Argument Manager any longer
87
88    // ----------- End Arguments Manager ---------
89    
90   
91  // Read the Raw file  
92    std::ifstream *Fp = new std::ifstream(inputFileName, std::ios::in | std::ios::binary);
93    if ( ! *Fp )
94    {   
95       std::cout << "Cannot open file: " << inputFileName;
96       delete Fp;
97       Fp = 0;
98       return 0;
99    }  
100
101    std::string strPixelType(pixelType);
102    int pixelSign;
103    int pixelSize;
104    
105    if (strPixelType == "8S")
106    {
107       pixelSize = 1;
108       pixelSign = 0;
109    }
110    else if (strPixelType == "8U")
111    {
112       pixelSize = 1;
113       pixelSign = 1;
114    }
115    else if (strPixelType == "16S")
116    {
117       pixelSize = 2;
118       pixelSign = 0; 
119    }   
120    else if (strPixelType == "16U")
121    {
122       pixelSize = 2;
123       pixelSign = 1;
124    }      
125    else if (strPixelType == "32S")
126    {
127       pixelSize = 4;
128       pixelSign = 0;
129    }   
130    else if (strPixelType == "32U")
131    {
132       pixelSize = 4;
133       pixelSign = 1;
134    }
135    else
136    {
137       std::cout << "Wrong 'pixeltype' (" << strPixelType << ")" << std::endl;
138       return 1;
139    }
140    
141    int dataSize =  nX*nY*nZ*pixelSize*samplesPerPixel;
142    uint8_t *pixels = new uint8_t[dataSize];
143    
144    Fp->read((char*)pixels, (size_t)dataSize);
145   
146
147 // Create an empty FileHelper
148
149    gdcm::FileHelper *fileH = gdcm::FileHelper::New();
150  
151  // Get the (empty) image header.  
152    gdcm::File *fileToBuild = fileH->GetFile();
153      
154    
155    // If you want to use this program as a template to create
156    // a 'Single Study UID - Single Serie UID' file set
157    // keep the following lines out of the loop
158
159    // 'Study Instance UID'
160    // The user is allowed to create his own Study, 
161    //          keeping the same 'Study Instance UID' for various images
162    // The user may add images to a 'Manufacturer Study',
163    //          adding new Series to an already existing Study
164    std::string studyUID =  gdcm::Util::CreateUniqueUID(); 
165    fileToBuild->InsertEntryString(studyUID, 0x0020,0x000d,"UI");
166
167    // 'Serie Instance UID'
168    // The user is allowed to create his own Series, 
169    // keeping the same 'Serie Instance UID' for various images
170    // The user shouldn't add any image to a 'Manufacturer Serie'
171    // but there is no way no to prevent him for doing that
172    std::string serieUID =  gdcm::Util::CreateUniqueUID();    
173    fileToBuild->InsertEntryString(serieUID, 0x0020,0x000e,"UI");   
174  
175    // end of 'keep out of loop lines  
176    
177    std::ostringstream str;
178
179    // Set the image size
180    str.str("");
181    str << nX;
182    fileToBuild->InsertEntryString(str.str(),0x0028,0x0011, "US"); // Columns
183    str.str("");
184    str << nY;
185    fileToBuild->InsertEntryString(str.str(),0x0028,0x0010, "US"); // Rows
186    
187    str.str("");
188    str << nZ;
189    fileToBuild->InsertEntryString(str.str(),0x0028,0x0008, "IS"); // Number of Frames
190
191    // Set the pixel type
192    
193    str.str("");
194    str << pixelSize*8;
195    fileToBuild->InsertEntryString(str.str(),0x0028,0x0100, "US"); // Bits Allocated
196
197    str.str("");
198    str << pixelSize*8;
199    fileToBuild->InsertEntryString(str.str(),0x0028,0x0101, "US"); // Bits Stored
200
201    str.str("");
202    str << ( pixelSize*8 - 1 );
203    fileToBuild->InsertEntryString(str.str(),0x0028,0x0102, "US"); // High Bit
204
205    str.str("");
206    str << pixelSign;
207    fileToBuild->InsertEntryString(str.str(),0x0028,0x0103, "US"); // Pixel Representation
208
209    str.str("");
210    str << samplesPerPixel;
211    
212 // If you deal with a Serie of images, it up to you to tell gdcm,
213 // for each image, what are the values of :
214 // 0020 0032 DS 3 Image Position (Patient)
215 // 0020 0037 DS 6 Image Orientation (Patient)
216
217    fileToBuild->InsertEntryString(str.str(),0x0028,0x0002, "US"); // Samples per Pixel
218
219    if (strlen(patientName) != 0)
220       fileToBuild->InsertEntryString(patientName,0x0010,0x0010, "PN"); // Patient's Name
221    
222    
223 // Set the image Pixel Data
224    fileH->SetImageData(pixels,dataSize);
225
226 // Set the writting mode and write the image
227    fileH->SetWriteModeToRaw();
228
229  // Write a DICOM Explicit VR file
230    fileH->SetWriteTypeToDcmExplVR();
231
232    if( !fileH->Write(outputFileName ) )
233    {
234       std::cout << "Failed for [" << outputFileName << "]\n"
235                 << "           File is unwrittable\n";
236    }
237
238    fileH->Delete();
239
240    delete[] pixels;
241    return 1;
242 }