/*========================================================================= Program: gdcm Module: $RCSfile: TestPapyrus.cxx,v $ Language: C++ Date: $Date: 2005/01/19 17:49:42 $ Version: $Revision: 1.1 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "gdcmHeader.h" #include "gdcmFile.h" #include "gdcmDocument.h" #include "gdcmValEntry.h" #include "gdcmBinEntry.h" #include "gdcmSeqEntry.h" #include "gdcmSQItem.h" //#include #ifndef _WIN32 #include //for access, unlink #else #include //for _access #endif // return true if the file exists bool FileExists(const char* filename) { #ifdef _MSC_VER # define access _access #endif #ifndef R_OK # define R_OK 04 #endif if ( access(filename, R_OK) != 0 ) { return false; } else { return true; } } bool RemoveFile(const char* source) { #ifdef _MSC_VER #define _unlink unlink #endif return unlink(source) != 0 ? false : true; } // ---------------------------------------------------------------------- // Here we load a supposed to be Papyrus File (gdcm::Header compliant) // and then try to get the pixels, using low-level SeqEntry accessors. // Since it's not a general purpose Papyrus related program // (just a light example) we suppose *everything* is clean // and we don't perform any integrity check // ---------------------------------------------------------------------- // TODO : finish writing the program ! int main(int argc, char* argv[]) { if (argc < 3) { std::cerr << "Usage :" << std::endl << argv[0] << " input_papyrus output_dicom" << std::endl; return 1; } std::string filename = argv[1]; std::string output = argv[2]; if( FileExists( output.c_str() ) ) { if( !RemoveFile( output.c_str() ) ) { std::cerr << "Ouch, the file exist, but I cannot remove it" << std::endl; return 1; } } gdcm::File *original = new gdcm::File( filename ); gdcm::Header *h = original->GetHeader(); // Look for private Papyrus Sequence gdcm::SeqEntry *seqPapyrus= h->GetSeqEntry(0x0041, 0x1050); if (!h) { std::cout << "NOT a Papyrus File" << std::endl; delete h; return 1; } gdcm::SQItem *sqi = seqPapyrus->GetFirstEntry(); if (sqi == 0) { std::cout << "NO SQItem found within private Papyrus Sequence" << std::endl; delete h; return 1; } // Get informations on the file : // Modality, Transfer Syntax, Study Date, Study Time // Patient Name, etc std::string TransferSyntax; std::string StudyDate; std::string StudyTime; std::string Modality; std::string PatientName; TransferSyntax = h->GetEntry(0x0002,0x0010); StudyDate = sqi->GetEntry(0x0008,0x0020); StudyTime = sqi->GetEntry(0x0008,0x0030); Modality = sqi->GetEntry(0x0008,0x0060); PatientName = sqi->GetEntry(0x0010,0x0010); std::cout << "TransferSyntax " << TransferSyntax << std::endl; std::string Rows; std::string Columns; std::string SamplesPerPixel; std::string BitsAllocated; std::string BitsStored; std::string HighBit; std::string PixelRepresentation; // just convert those needed to compute PixelArea length int iRows = (uint32_t) atoi( Rows.c_str() ); int iColumns = (uint32_t) atoi( Columns.c_str() ); int iSamplesPerPixel = (uint32_t) atoi( SamplesPerPixel.c_str() ); int iBitsAllocated = (uint32_t) atoi( BitsAllocated.c_str() ); int lgrImage = iRows*iColumns * iSamplesPerPixel * (iSamplesPerPixel/8); // we brutally suppose all the images within a Papyrus file // have the same caracteristics. // if you're aware they have not, just move the GetEntry // inside the loop // Get caracteristics of the first image SamplesPerPixel = sqi->GetEntry(0x0028,0x0002); Rows = sqi->GetEntry(0x0028,0x0010); Columns = sqi->GetEntry(0x0028,0x0011); BitsAllocated = sqi->GetEntry(0x0028,0x0100); BitsStored = sqi->GetEntry(0x0028,0x0101); HighBit = sqi->GetEntry(0x0028,0x0102); PixelRepresentation = sqi->GetEntry(0x0028,0x0102); // compute number of images int nbImages = 0; while (sqi) { nbImages++; sqi = seqPapyrus->GetNextEntry(); } std::cout <<"Number of frames :" << nbImages << std::endl; // allocate enough room to get the pixels of all images. uint8_t *PixelArea = new uint8_t[lgrImage*nbImages]; uint8_t *currentPosition = PixelArea; gdcm::BinEntry *pixels; // declare and open the file std::ifstream *Fp; Fp = new std::ifstream(filename.c_str(), std::ios::in | std::ios::binary); if( ! *Fp ) { std::cout << "Cannot open file: " << filename << std::endl; //gdcmDebugMacro( "Cannot open file: " << filename.c_str() ); delete Fp; Fp = 0; return 0; } // to be sure to be at the beginning Fp->seekg(0, std::ios::end); uint32_t offset; std::string previousRows = Rows; sqi = seqPapyrus->GetFirstEntry(); while (sqi) { std::cout << "One more image read. Keep waiting" << std::endl; Rows = sqi->GetEntry(0x0028,0x0010); // minimum integrity check if (Rows != previousRows) { std::cout << "Consistency check failed " << std::endl; return 1; } // get the images pixels pixels = sqi->GetBinEntry(0x7fe0,0x0010); offset = pixels->GetOffset(); // perform a fseek, on offset length on the 'right' length Fp->seekg(offset, std::ios::beg); // perform a fread into the right place Fp->read((char *)currentPosition, (size_t)lgrImage); currentPosition +=lgrImage; std::string previousRowNb = Rows; sqi = seqPapyrus->GetNextEntry(); } // build up a new File, with file info + images info + global pixel area. gdcm::Header *n = new gdcm::Header(); n->InitializeDefaultHeader(); n->SetEntry(TransferSyntax, 0x0002,0x0010); n->SetEntry(StudyDate, 0x0008,0x0020); n->SetEntry(StudyTime, 0x0008,0x0030); n->SetEntry(Modality, 0x0008,0x0060); n->SetEntry(PatientName, 0x0010,0x0010); n->SetEntry(SamplesPerPixel, 0x0028,0x0002); n->SetEntry(Rows, 0x0028,0x0010); n->SetEntry(Columns, 0x0028,0x0011); n->SetEntry(BitsAllocated, 0x0028,0x0100); n->SetEntry(BitsStored, 0x0028,0x0101); n->SetEntry(HighBit, 0x0028,0x0102); n->SetEntry(PixelRepresentation,0x0028,0x0102); // create the file gdcm::File *file = new gdcm::File(n); file->SetImageData(PixelArea,lgrImage); file->SetWriteTypeToDcmExplVR(); file->Print(); // Write the file file->Write(argv[2]); if (!file) { std::cout <<"Fail to open (write) file:[" << argv[2]<< "]" << std::endl;; return 1; } /* std::ofstream *fp2; fp2 = new std::ofstream(argv[2], std::ios::out | std::ios::binary ); if (!fp2) { std::cout <<"Fail to open (write) file:" << argv[2] << std::endl;; return 1; } if( !fp2->write((char *)PixelArea, lgrImage) ) { std::cout << "Failed\n" << "File in unwrittable :[" << argv[2] << "]" << std::endl; delete fp2; delete n; delete[] PixelArea; return 1; } fp2->close(); */ return 0; }