]> Creatis software - gdcm.git/blob - Example/TestPapyrus.cxx
893ab8cd1277d30a8dfad9df3b5de88a48592fd2
[gdcm.git] / Example / TestPapyrus.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: TestPapyrus.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/01/19 17:49:42 $
7   Version:   $Revision: 1.1 $
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 "gdcmHeader.h"
19 #include "gdcmFile.h"
20 #include "gdcmDocument.h"
21 #include "gdcmValEntry.h"
22 #include "gdcmBinEntry.h"
23 #include "gdcmSeqEntry.h"
24 #include "gdcmSQItem.h"
25
26 //#include <fstream>
27
28 #ifndef _WIN32
29 #include <unistd.h> //for access, unlink
30 #else
31 #include <io.h> //for _access
32 #endif
33
34 // return true if the file exists
35 bool FileExists(const char* filename)
36 {
37 #ifdef _MSC_VER
38 # define access _access
39 #endif
40 #ifndef R_OK
41 # define R_OK 04
42 #endif
43   if ( access(filename, R_OK) != 0 )
44     {
45     return false;
46     }
47   else
48     {
49     return true;
50     }
51 }
52
53 bool RemoveFile(const char* source)
54 {
55 #ifdef _MSC_VER
56 #define _unlink unlink
57 #endif
58   return unlink(source) != 0 ? false : true;
59 }
60
61 // ----------------------------------------------------------------------
62 // Here we load a supposed to be Papyrus File (gdcm::Header compliant)
63 // and then try to get the pixels, using low-level SeqEntry accessors.
64 // Since it's not a general purpose Papyrus related program
65 // (just a light example) we suppose *everything* is clean
66 // and we don't perform any integrity check
67 // ----------------------------------------------------------------------
68
69 // TODO : finish writing the program !
70
71 int main(int argc, char* argv[])
72 {
73    if (argc < 3)
74    {
75       std::cerr << "Usage :" << std::endl << 
76       argv[0] << " input_papyrus output_dicom" << std::endl;
77       return 1;
78    }
79
80    std::string filename = argv[1];
81    std::string output = argv[2];
82
83    if( FileExists( output.c_str() ) )
84    {
85       if( !RemoveFile( output.c_str() ) )
86       {
87          std::cerr << "Ouch, the file exist, but I cannot remove it" << std::endl;
88          return 1;
89       }
90    }
91    gdcm::File *original = new gdcm::File( filename );
92    gdcm::Header *h = original->GetHeader();
93
94    // Look for private Papyrus Sequence
95    gdcm::SeqEntry *seqPapyrus= h->GetSeqEntry(0x0041, 0x1050);
96    if (!h)
97    {
98       std::cout << "NOT a Papyrus File" << std::endl;
99       delete h;
100       return 1;
101    }
102
103    gdcm::SQItem *sqi = seqPapyrus->GetFirstEntry();
104    if (sqi == 0)
105    {
106       std::cout << "NO SQItem found within private Papyrus Sequence"
107           << std::endl;
108       delete h;
109       return 1;
110    }
111
112 // Get informations on the file : 
113 //  Modality, Transfer Syntax, Study Date, Study Time
114 // Patient Name, etc
115       
116    std::string TransferSyntax;
117    std::string StudyDate;
118    std::string StudyTime;
119    std::string Modality;
120    std::string PatientName;
121
122    TransferSyntax      =   h->GetEntry(0x0002,0x0010);
123    StudyDate           = sqi->GetEntry(0x0008,0x0020);
124    StudyTime           = sqi->GetEntry(0x0008,0x0030);
125    Modality            = sqi->GetEntry(0x0008,0x0060);
126    PatientName         = sqi->GetEntry(0x0010,0x0010);
127
128    std::cout << "TransferSyntax " << TransferSyntax << std::endl;
129
130    std::string Rows;
131    std::string Columns;
132    std::string SamplesPerPixel;
133    std::string BitsAllocated;
134    std::string BitsStored;
135    std::string HighBit;
136    std::string PixelRepresentation;
137
138    // just convert those needed to compute PixelArea length
139    int iRows            = (uint32_t) atoi( Rows.c_str() );
140    int iColumns         = (uint32_t) atoi( Columns.c_str() );
141    int iSamplesPerPixel = (uint32_t) atoi( SamplesPerPixel.c_str() );
142    int iBitsAllocated   = (uint32_t) atoi( BitsAllocated.c_str() );
143
144    int lgrImage = iRows*iColumns * iSamplesPerPixel * (iSamplesPerPixel/8);
145
146    // we brutally suppose all the images within a Papyrus file
147    // have the same caracteristics.
148    // if you're aware they have not, just move the GetEntry
149    // inside the loop
150
151    // Get caracteristics of the first image
152
153    SamplesPerPixel     = sqi->GetEntry(0x0028,0x0002);
154    Rows                = sqi->GetEntry(0x0028,0x0010);
155    Columns             = sqi->GetEntry(0x0028,0x0011);
156    BitsAllocated       = sqi->GetEntry(0x0028,0x0100);
157    BitsStored          = sqi->GetEntry(0x0028,0x0101);
158    HighBit             = sqi->GetEntry(0x0028,0x0102);
159    PixelRepresentation = sqi->GetEntry(0x0028,0x0102);
160
161    // compute number of images
162    int nbImages = 0;
163    while (sqi)
164    {
165       nbImages++;
166       sqi =  seqPapyrus->GetNextEntry();
167    }
168    std::cout <<"Number of frames :" << nbImages << std::endl;  
169
170    //  allocate enough room to get the pixels of all images.
171
172    uint8_t *PixelArea = new uint8_t[lgrImage*nbImages];
173    uint8_t *currentPosition = PixelArea;
174    gdcm::BinEntry *pixels;
175
176    // declare and open the file
177    std::ifstream *Fp;
178    Fp = new std::ifstream(filename.c_str(), std::ios::in | std::ios::binary);
179    if( ! *Fp )
180    {
181       std::cout <<  "Cannot open file: " << filename << std::endl;
182       //gdcmDebugMacro( "Cannot open file: " << filename.c_str() );
183       delete Fp;
184       Fp = 0;
185       return 0;
186    }
187    // to be sure to be at the beginning
188    Fp->seekg(0,  std::ios::end);
189
190    uint32_t offset;
191    std::string previousRows = Rows;
192    sqi = seqPapyrus->GetFirstEntry();
193    while (sqi)
194    {
195       std::cout << "One more image read. Keep waiting" << std::endl;
196       Rows = sqi->GetEntry(0x0028,0x0010);
197       // minimum integrity check
198       if (Rows != previousRows)
199       {
200          std::cout << "Consistency check failed " << std::endl;
201          return 1;
202       }
203       // get the images pixels
204       pixels = sqi->GetBinEntry(0x7fe0,0x0010);
205       offset = pixels->GetOffset();
206       // perform a fseek, on offset length on the 'right' length
207       Fp->seekg(offset, std::ios::beg);
208       // perform a fread into the right place
209       Fp->read((char *)currentPosition, (size_t)lgrImage);
210       currentPosition +=lgrImage;
211
212       std::string previousRowNb = Rows;
213       sqi =  seqPapyrus->GetNextEntry();
214    }
215
216    // build up a new File, with file info + images info + global pixel area.
217
218    gdcm::Header *n = new gdcm::Header();
219    n->InitializeDefaultHeader();
220
221    n->SetEntry(TransferSyntax,     0x0002,0x0010);
222    n->SetEntry(StudyDate,          0x0008,0x0020);
223    n->SetEntry(StudyTime,          0x0008,0x0030);
224    n->SetEntry(Modality,           0x0008,0x0060);
225    n->SetEntry(PatientName,        0x0010,0x0010);
226
227    n->SetEntry(SamplesPerPixel,    0x0028,0x0002);
228    n->SetEntry(Rows,               0x0028,0x0010);
229    n->SetEntry(Columns,            0x0028,0x0011);
230    n->SetEntry(BitsAllocated,      0x0028,0x0100);
231    n->SetEntry(BitsStored,         0x0028,0x0101);
232    n->SetEntry(HighBit,            0x0028,0x0102);
233    n->SetEntry(PixelRepresentation,0x0028,0x0102);
234
235    // create the file
236    gdcm::File *file = new gdcm::File(n);
237
238    file->SetImageData(PixelArea,lgrImage);
239    file->SetWriteTypeToDcmExplVR();
240
241    file->Print();
242
243    // Write the file
244    file->Write(argv[2]); 
245    if (!file)
246    {
247       std::cout <<"Fail to open (write) file:[" << argv[2]<< "]" << std::endl;;
248       return 1;  
249    }
250 /*    
251   std::ofstream *fp2;
252   fp2 =  new std::ofstream(argv[2], std::ios::out | std::ios::binary );
253   
254   if (!fp2)
255   {
256       std::cout <<"Fail to open (write) file:" << argv[2]  << std::endl;;
257       return 1;  
258   }
259    if( !fp2->write((char *)PixelArea, lgrImage) )
260    {
261       std::cout << "Failed\n"
262                 << "File in unwrittable :["
263                 << argv[2] << "]" << std::endl;
264  
265       delete fp2;
266       delete n;
267       delete[] PixelArea;
268       return 1;
269    }
270    fp2->close();
271  */
272  
273    return 0;
274 }