1 /*=========================================================================
4 Module: $RCSfile: exReadPapyrus.cxx,v $
6 Date: $Date: 2005/02/03 15:44:50 $
7 Version: $Revision: 1.1 $
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.
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.
17 =========================================================================*/
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"
31 #include <unistd.h> //for access, unlink
33 #include <io.h> //for _access
36 // return true if the file exists
37 bool FileExists(const char *filename)
40 # define access _access
45 if ( access(filename, R_OK) != 0 )
55 bool RemoveFile(const char *source)
58 #define _unlink unlink
60 return unlink(source) != 0 ? false : true;
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 // ----------------------------------------------------------------------
71 int main(int argc, char *argv[])
75 std::cerr << "Usage :" << std::endl <<
76 argv[0] << " input_papyrus output_dicom verbose" << std::endl;
80 std::string filename = argv[1];
81 std::string output = argv[2];
84 gdcm::Debug::DebugOn();
86 if( FileExists( output.c_str() ) )
88 if( !RemoveFile( output.c_str() ) )
90 std::cerr << "Ouch, the file exist, but I cannot remove it" << std::endl;
94 gdcm::FileHelper *original = new gdcm::FileHelper( filename );
95 gdcm::File *h = original->GetFile();
97 // Look for private Papyrus Sequence
98 gdcm::SeqEntry *seqPapyrus= h->GetSeqEntry(0x0041, 0x1050);
101 std::cout << "NOT a Papyrus File" << std::endl;
106 gdcm::SQItem *sqi = seqPapyrus->GetFirstSQItem();
109 std::cout << "NO SQItem found within private Papyrus Sequence"
115 std::string TransferSyntax;
116 std::string StudyDate;
117 std::string StudyTime;
118 std::string Modality;
119 std::string PatientName;
120 std::string MediaStSOPinstUID;
122 // Get informations on the file :
123 // Modality, Transfer Syntax, Study Date, Study Time
124 // Patient Name, Media Storage SOP Instance UID, etc
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);
133 std::cout << "TransferSyntax " << TransferSyntax << std::endl;
137 std::string SamplesPerPixel;
138 std::string BitsAllocated;
139 std::string BitsStored;
141 std::string PixelRepresentation;
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
149 // Get caracteristics of the first image
150 SamplesPerPixel = sqi->GetEntryValue(0x0028,0x0002);
151 Rows = sqi->GetEntryValue(0x0028,0x0010);
152 Columns = sqi->GetEntryValue(0x0028,0x0011);
153 BitsAllocated = sqi->GetEntryValue(0x0028,0x0100);
154 BitsStored = sqi->GetEntryValue(0x0028,0x0101);
155 HighBit = sqi->GetEntryValue(0x0028,0x0102);
156 PixelRepresentation = sqi->GetEntryValue(0x0028,0x0102);
158 // just convert those needed to compute PixelArea length
159 int iRows = (uint32_t) atoi( Rows.c_str() );
160 int iColumns = (uint32_t) atoi( Columns.c_str() );
161 int iSamplesPerPixel = (uint32_t) atoi( SamplesPerPixel.c_str() );
162 int iBitsAllocated = (uint32_t) atoi( BitsAllocated.c_str() );
164 int lgrImage = iRows*iColumns * iSamplesPerPixel * (iBitsAllocated/8);
166 // compute number of images
167 int nbImages = seqPapyrus->GetNumberOfSQItems();
168 std::cout <<"Number of frames :" << nbImages << std::endl;
170 // allocate enough room to get the pixels of all images.
171 uint8_t *PixelArea = new uint8_t[lgrImage*nbImages];
172 uint8_t *currentPosition = PixelArea;
173 gdcm::BinEntry *pixels;
175 // declare and open the file
177 Fp = new std::ifstream(filename.c_str(), std::ios::in | std::ios::binary);
180 std::cout << "Cannot open file: " << filename << std::endl;
181 //gdcmDebugMacro( "Cannot open file: " << filename.c_str() );
186 // to be sure to be at the beginning
187 Fp->seekg(0, std::ios::end);
190 std::string previousRows = Rows;
191 sqi = seqPapyrus->GetFirstSQItem();
194 std::cout << "One more image read. Keep waiting" << std::endl;
195 Rows = sqi->GetEntryValue(0x0028,0x0010);
196 // minimum integrity check
197 if (Rows != previousRows)
199 std::cout << "Consistency check failed " << std::endl;
202 // get the images pixels
203 pixels = sqi->GetBinEntry(0x7fe0,0x0010);
204 offset = pixels->GetOffset();
205 // perform a fseek, on offset length on the 'right' length
206 Fp->seekg(offset, std::ios::beg);
207 // perform a fread into the right place
208 Fp->read((char *)currentPosition, (size_t)lgrImage);
209 currentPosition +=lgrImage;
211 std::string previousRowNb = Rows;
213 sqi = seqPapyrus->GetNextSQItem();
216 // build up a new File, with file info + images info + global pixel area.
218 std::string NumberOfFrames = gdcm::Util::Format("%d", nbImages);
220 gdcm::File *n = new gdcm::File();
222 n->InsertValEntry(MediaStSOPinstUID, 0x0002,0x0002);
223 // Whe keep default gdcm Transfer Syntax (Explicit VR Little Endian)
224 // since using Papyrus one (Implicit VR Little Endian) is a mess
225 //n->InsertValEntry(TransferSyntax, 0x0002,0x0010);
226 n->InsertValEntry(StudyDate, 0x0008,0x0020);
227 n->InsertValEntry(StudyTime, 0x0008,0x0030);
228 n->InsertValEntry(Modality, 0x0008,0x0060);
229 n->InsertValEntry(PatientName, 0x0010,0x0010);
231 n->InsertValEntry(SamplesPerPixel, 0x0028,0x0002);
232 n->InsertValEntry(NumberOfFrames, 0x0028,0x0008);
233 n->InsertValEntry(Rows, 0x0028,0x0010);
234 n->InsertValEntry(Columns, 0x0028,0x0011);
235 n->InsertValEntry(BitsAllocated, 0x0028,0x0100);
236 n->InsertValEntry(BitsStored, 0x0028,0x0101);
237 n->InsertValEntry(HighBit, 0x0028,0x0102);
238 n->InsertValEntry(PixelRepresentation,0x0028,0x0102);
241 gdcm::FileHelper *file = new gdcm::FileHelper(n);
243 file->SetImageData(PixelArea,lgrImage*nbImages);
244 file->SetWriteTypeToDcmExplVR();
246 //file->SetPrintLevel(2);
250 file->Write(argv[2]);
253 std::cout <<"Fail to open (write) file:[" << argv[2]<< "]" << std::endl;;