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