From 4dda77ff722a08898ae9ca75eacce0f11336cf12 Mon Sep 17 00:00:00 2001 From: jpr Date: Wed, 19 Jan 2005 17:49:42 +0000 Subject: [PATCH] Add a *very* simple test program to read the frames of a Papyrus image, using low level accessors (Not yet fully checked) --- Example/CMakeLists.txt | 1 + Example/TestPapyrus.cxx | 274 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 275 insertions(+) create mode 100644 Example/TestPapyrus.cxx diff --git a/Example/CMakeLists.txt b/Example/CMakeLists.txt index 3eb21a2f..e9f8d4ea 100644 --- a/Example/CMakeLists.txt +++ b/Example/CMakeLists.txt @@ -18,6 +18,7 @@ SET(EXAMPLE_SOURCES TestFromScratch TestReadWriteReadCompare TestDcm2Acr + TestPapyrus TestWrite TestWriteSimple Volume2Dicom diff --git a/Example/TestPapyrus.cxx b/Example/TestPapyrus.cxx new file mode 100644 index 00000000..893ab8cd --- /dev/null +++ b/Example/TestPapyrus.cxx @@ -0,0 +1,274 @@ +/*========================================================================= + + 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; +} -- 2.45.1